Skip to main content

Create a customer

POSThttps://api.fieldtask.example/public/v1/customers
Permissions
customers:create, customers:read
Safe retries
Idempotency-Key
Also available as
fieldtask_create_customer

Creates one customer in the organization your credential is connected to.

Only name is required. You can also save an email address, a phone number, a display color and your own system's identifier for the customer.

This endpoint only creates. It never matches, updates or restores an existing customer, even one with the same name. If you send the same body twice without the same Idempotency-Key, you get two customers, or a 422 if the body includes an email address that's now in use. See Idempotency and safe retries.

Preview

This page is generated from contract 2026-11-03-review.2, a review export that hasn't been released.

Before you start​

You need:

  1. API access for your organization. An owner or admin requests it in Settings → API connections. Until FieldTask enables it, every request returns 403 api_access_not_enabled.
  2. A REST credential with the permissions below: an API token created in Settings → API connections, or an access token from an OAuth client-credentials connection. Tokens from an MCP sign-in don't work with the REST API.
  3. A check that the customer doesn't already exist. If you created it earlier with an external_reference, look it up with GET /public/v1/customers?external_reference=…. Otherwise page through GET /public/v1/customers and compare names and email addresses.

To add the customer's service address, create a location for it next with POST /public/v1/customers/{customer_id}/locations. A customer can't be given an address in this request.

Permissions​

Every request needs all of these permissions:

PermissionDependency in the permission map
customers:createDepends on customers:read
customers:readNo dependencies

No field needs an additional permission.

Adding a permission to a connection doesn't happen automatically. An owner or admin edits it in Settings → API connections. API tokens keep the same token string when their permissions change. OAuth integrations must also request the new scope when they get an access token.

Request​

Responses​

Created

Response Headers
    Cache-Control

    Responses must not be cached.

    Idempotency-Key

    The operation key used for this create, including a server-generated key when omitted.

    Idempotency-Replayed
    Location
    Operation-Location
    X-Request-ID

    Server-generated request correlation ID.

Field guide​

The request body is a single JSON object. Only name is required. Every optional field you leave out is saved as null.

FieldRequiredWhat to send
nameYesThe customer's name, at most 256 characters. Spaces at either end are removed; what remains can't be empty. Control characters, including tabs and line breaks, aren't allowed. Names don't have to be unique.
emailNoA valid email address of at most 256 characters, or null. It must not already belong to another customer in your organization. See Email addresses. Defaults to null.
phone_numberNoInternational format: +, the country code and the number, with no spaces or punctuation, such as +15555550100. The first digit after + can't be 0, and there can be 2–15 digits. Defaults to null.
colorNoA display color as # followed by six hexadecimal digits, such as #336699. Defaults to null.
external_referenceNoYour system's identifier for this customer. See External references. Omit it rather than sending null.

Anything else in the body is rejected with 422 validation_failed. That includes fields that appear in the response, such as primary_address and is_archived, and organization_id. The organization always comes from your credential.

A new customer is never archived, and its primary_address is null. The first location you add to the customer can fill in primary_address; see Create a customer location.

Body and header rules​

  • Send Content-Type: application/json with an uncompressed body. A Content-Encoding header is rejected with 415.
  • The body can be at most 256 KiB and nest at most 10 levels deep.
  • Duplicate property names, NaN and Infinity are rejected with 400 invalid_json.
  • The URL must have no query string.

Email addresses​

Each customer email address can belong to only one customer in your organization.

  • If another customer already has the address, the request is rejected with 422 validation_failed. The response doesn't say which customer has it, or that the email was the problem.
  • The check includes customers that were deleted in FieldTask. A deleted customer doesn't appear in lists but still holds its email address.
  • The address is stored exactly as sent. It isn't trimmed or lowercased, and spaces at either end are rejected. Uniqueness is case-sensitive, so Facilities@example.com and facilities@example.com count as different addresses. Normalize case in your own system if you want to avoid near-duplicates.
  • Customers without an email address never conflict with each other.

If you get a 422 and the rest of the body is valid, look for the existing customer with GET /public/v1/customers and compare email addresses. If you don't find it, it may have been deleted; create the customer without email, or ask an owner or admin to check in FieldTask.

External references​

external_reference stores your own system's identifier for the customer, so you can find it again without keeping FieldTask IDs.

  • It's 1–128 characters, can't be only whitespace and can't contain control characters.
  • It's stored exactly as sent: case-sensitive and never trimmed.
  • It's unique per organization and client application. A second customer with the same reference is rejected with 409 external_reference_conflict; the existing customer isn't changed.
  • It isn't returned in the customer body. Look a customer up with GET /public/v1/customers?external_reference=…. That parameter can't be combined with any other.

An external reference is not an idempotency key. Use both: the reference identifies the record in your system, and the key makes one request safe to retry. See External references.

Idempotency and safe retries​

Send an Idempotency-Key header with a new value, such as a UUID, for every new customer, and save it with your own record before sending. If you get no response, a timeout or a 5xx, send the same body with the same key again, with backoff.

SituationResult
New keyThe customer is created. Response 201, Idempotency-Replayed: false.
Same key, same body, within 7 daysThe original response is returned again. No second customer is created and it isn't counted against your daily create allowance. Response 201, Idempotency-Replayed: true.
Same key, different body409 idempotency_key_reused. Nothing is created.
Same key while the first request is still running409 operation_in_progress with Retry-After. Retry with the same key and body.
Same key more than 7 days later409 idempotency_window_expired. A key can never be reused for a different customer.
Same key, but the customer was deleted since410 resource_gone. Don't create it again automatically.

A replay returns the response as it was when the customer was created, not the customer's current state. Read the customer with GET /public/v1/customers/{resource_id} for current values.

A retry with the same key never fails because of the customer's own email address: the key is checked first, so you get the original 201 back. If you lost a response and then sent the body again with a new key, a 422 can mean the first attempt succeeded.

Keys are 16–128 printable ASCII characters and are scoped to the organization, the connection and the kind of request. Without a key, the server generates one and returns it in the Idempotency-Key response header, which only helps if you receive the response. For the full rules, see Idempotency and recovery.

What happens after the customer is saved​

A 201 response means the customer is saved in FieldTask. Nothing further is needed for it to exist, and later follow-up work never removes it. No external system is contacted during the request.

Any follow-up work is reported on the operation, not on the customer. Read the Operation-Location URL from the 201 response with the same credential (needs customers:read). See Get an operation for the status values.

Pending confirmation

In the review contract, customers created through the API aren't sent to a connected CRM. If your organization has external customer synchronization turned on, the operation reports a blocked target with configuration_required. Otherwise integration.status is not_applicable. The customer itself is created either way.

Operation results are kept for seven days. After that, GET /public/v1/operations/{id} returns 410 operation_result_expired. That doesn't mean the customer wasn't created.

Recovering from failures​

What happenedWhat to do
Timeout, connection error or 5xxRetry the same body with the same key, with exponential backoff.
409 operation_in_progress or 429Wait for Retry-After seconds and retry with the same key.
201 receivedStore data.id and the Location and Operation-Location headers. Stop retrying.
422 on a body that was accepted beforeThe email address may already be in use, possibly by the customer your first attempt created. See Email addresses.
Key older than 7 days, or the result expiredDon't create again yet. Look for the customer with GET /public/v1/customers?external_reference=… or your saved customer ID.

Never switch to a new key just because a response was lost. A new key means a new customer.

Errors​

Errors use application/problem+json. The top-level code is the stable machine-readable value; error adds a readable message, a suggested fix and a documentation link. For a missing permission, code is insufficient_scope and error.code is missing_permission. Validation errors don't say which field failed, and error responses never echo submitted values. See Errors.

StatuscodeMeaningWhat to do
400invalid_queryThe URL has a query string. Create requests accept none.Send the request to /public/v1/customers with no query parameters.
400invalid_jsonThe body isn't one valid JSON value, repeats a property name, uses NaN/Infinity or nests deeper than 10 levels.Send a single JSON object encoded as UTF-8.
400invalid_operation_keyIdempotency-Key isn't 16–128 printable ASCII characters.Use a UUID or another 16–128 character key without spaces at either end.
401invalid_tokenThe bearer token is missing, malformed, expired, revoked or issued for a different resource (for example an MCP sign-in).Send a current REST API token or REST OAuth access token as Authorization: Bearer ….
403api_access_not_enabledFieldTask hasn't enabled API access for this organization, or has disabled it.An owner or admin requests access in Settings → API connections.
403insufficient_scopeThe connection lacks customers:create or customers:read. error.code is missing_permission.Add the permission named in error.message to the connection, then retry with the same key.
403operation_forbiddenThe connection's access changed while the request was processed, or the result would include data the connection can no longer read.Check the connection's permissions, then retry. Retry creates with the same key and body.
404resource_not_foundThe public API isn't available in this environment, or the URL is wrong.Check the API origin and path.
405method_not_allowedCustomer creation isn't enabled in this environment. The Allow header lists the methods that are.Contact FieldTask if you expected customer creation to be available.
409external_reference_conflictAnother customer created through this client application already uses this external_reference. Nothing was updated.Find the existing customer with GET /public/v1/customers?external_reference=…. Use a new reference only for a genuinely new customer.
409idempotency_key_reusedThis key was already used with a different body.Resend the original body with this key, or use a new key for a different customer.
409operation_in_progressA request with the same key is still being processed.Wait for Retry-After seconds, then retry with the same key and body.
409idempotency_window_expiredThis key was used more than seven days ago. It can't be replayed or reused. This doesn't mean the original request failed.Reconcile using your saved customer ID or external_reference before creating anything new.
410resource_goneYou replayed a key whose customer has since been deleted in FieldTask.Don't create the customer again automatically. Check with an owner or admin whether it was removed on purpose.
413payload_too_largeThe body is larger than 256 KiB.Send a smaller body.
415unsupported_media_typeContent-Type isn't application/json, or the body is compressed.Send an uncompressed body with Content-Type: application/json.
422validation_failedA field is missing, unknown or invalid, or email already belongs to another customer in the organization, including a deleted one.Check the request against the field guide. If only the email can be wrong, see Email addresses. The response doesn't name the field.
429rate_limit_exceededToo many requests in the current minute, or too many concurrent requests, for the organization or connection.Wait for Retry-After seconds. Retry creates with the same key.
429daily_quota_exceededThe organization or connection has used its daily create allowance. Allowances reset at 00:00 UTC.Wait for Retry-After seconds, or check remaining allowance in Settings → API connections.
503temporarily_unavailableThe service couldn't complete the request. The customer may or may not have been created.Retry with the same key and body, with exponential backoff.

Every response, including errors, has an X-Request-ID header. Include it, with the time and the status code, when you contact support. Never send tokens or secrets.

Limits​

Customer creates count against the same per-minute, concurrency and daily create limits as other creates. Replaying an already-created customer with its original key doesn't count as another create. See Rate limits.

Response headers​

A successful create returns 201 Created with these headers:

HeaderAlways presentValue
Cache-ControlYesAlways no-store
Idempotency-KeyYesstring
Idempotency-ReplayedYestrue or false
LocationYesuri-reference
Operation-LocationYesuri-reference
X-Request-IDYesuuid

Location is the customer's URL, /public/v1/customers/{id}. The server also returns the Idempotency-Key that was used, including one it generated.