Skip to main content

Contacts

Contacts store the customer and supplier details that power invoices, purchases, subscriptions, and reconciliation. Use these mutations and queries to keep your CRM in sync or to enrich documents you create via the API.

Prerequisites​

  • A Naqood API secret or OAuth-issued secret scoped to the target organization
  • The organization slug for every request
  • A role that can manage contacts in that organization

Contact fields​

Contact objects carry both commercial terms and basic profile data.

FieldTypeNotes
idID!Stable identifier
nameString!Display name used across documents
typeString!Free-form label (for example company or individual)
email / phoneEmail / StringOptional contact details
address...postalCodeStringOptional address lines
country / emirate / pOBoxCountry / StringRegional details
companyId / vatStringRegistration numbers, when applicable
paymentTermTypeString!How due dates are calculated (days, current_month, etc.)
paymentTermDaysInt!Days applied to the payment term
isCustomerBoolean!Marks the contact for sales flows
isSupplierBoolean!Marks the contact for purchase flows
accountAccountOptional default posting account
vatId / defaultVatID / VatOptional default VAT code applied on supplier bills
archivedBoolean!Hides the contact without deleting it
isDeletableBooleanHelpful hint before calling deleteContact
createdAt / updatedAtTimestamp!Audit timestamps

Fetch a single contact​

Retrieve the full contact profile when you have its ID.

query Contact($contactID: ID!) {
contact(contactID: $contactID) {
id
name
type
email
phone
paymentTermType
paymentTermDays
isCustomer
isSupplier
archived
account {
id
code
name
}
vatId
defaultVat {
id
code
name
}
}
}

List contacts​

Page through contacts within an organization and apply filters or sorting.

query Contacts(
$slug: Slug!
$offset: Int
$limit: Int
$orderBy: OrderByInput
$filter: JSONObject
) {
organization(slug: $slug) {
contacts(
offset: $offset
limit: $limit
orderBy: $orderBy
filter: $filter
) {
count
entries
}
}
}
  • filter supports the standard operators (equalTo, notEqualTo, greaterThan, lessThanOrEqualTo, in, plus and/or groups).
  • entries returns contact objects (same shape as Contact) as JSON blobs so you can hydrate your own models.

Create a contact​

mutation CreateContact($input: CreateContactInput!) {
createContact(input: $input)
}

CreateContactInput highlights:

FieldRequiredNotes
slug✅Organization issuing the contact
name✅Display name
type✅Free-form label shown in the UI
paymentTermType✅days, current_month
paymentTermDays✅Number of days applied to the term
isCustomer✅true if the contact should appear in sales flows
isSupplier✅true if the contact should appear in purchasing
accountIdOptionalDefault ledger account for postings
vatIdOptionalDefault VAT code for supplier bills. Must belong to the organization.
Address, tax IDs, and comms fieldsOptionalPopulate as needed

Example variables:

{
"input": {
"slug": "acme-co",
"name": "Acme Supplies",
"type": "company",
"email": "billing@acme.test",
"paymentTermType": "days",
"paymentTermDays": 30,
"isCustomer": false,
"isSupplier": true,
"accountId": "a42d5b18-aaaa-bbbb-cccc-1234567890ab",
"vatId": "b53e6c29-bbbb-cccc-dddd-1234567890ab"
}
}

Bulk create contacts​

Create many contacts in a single request. The whole batch is created in one transaction: if any contact fails validation, none are saved.

mutation CreateContacts($input: CreateContactsInput!) {
createContacts(input: $input)
}

CreateContactsInput highlights:

FieldRequiredNotes
slug✅Organization issuing the contacts
contacts✅Array of contacts (same fields as create, without slug). Maximum 1000 per request.

Example variables:

{
"input": {
"slug": "acme-co",
"contacts": [
{
"name": "Acme Supplies",
"type": "company",
"email": "billing@acme.test",
"paymentTermType": "days",
"paymentTermDays": 30,
"isCustomer": false,
"isSupplier": true
},
{
"name": "Acme Retail",
"type": "company",
"email": "retail@acme.test",
"paymentTermType": "days",
"paymentTermDays": 14,
"isCustomer": true,
"isSupplier": false
}
]
}
}

Update a contact​

mutation UpdateContact($input: UpdateContactInput!) {
updateContact(input: $input) {
id
name
email
paymentTermType
paymentTermDays
archived
}
}

Provide the id plus the updated fields. Required properties (name, type, paymentTermType, paymentTermDays, isCustomer, isSupplier, slug) must still be present even when other fields are unchanged.

Archive, restore, or delete​

  • Archive: archiveContact(contactID: ID!) hides a contact from pickers without losing history.
  • Restore: unarchiveContact(contactID: ID!) brings it back.
  • Delete: deleteContact(contactID: ID!) permanently removes a contact that has not been used on journal entries. Check the isDeletable flag first to avoid conflicts.