Skip to main content

Errors

Every error response has the same JSON body:

{
"error": "Unauthorized",
"message": "A valid API key is required.",
"code": "unauthenticated",
"requestId": "0196f0a3-1d2e-7f40-8a5b-6c7d8e9f0a1b"
}
  • error is the HTTP status text.
  • message explains the problem. Do not parse it; the wording can change.
  • code is a stable, machine-readable value, present on every error. Branch on code, not on message.
  • requestId identifies the request in Harmony's logs.

Some errors add fields that help you resolve them. The API reference lists them for each operation.

Every response, successful or not, also carries the request ID in the x-request-id header. Include it when you contact Harmony support about a failed request.

Codes​

  • unauthenticated (401): the API key is missing, unknown, or revoked.
  • forbidden (403): the API key's user has a role that does not allow the operation, such as a Viewer importing contacts or creating a webhook endpoint.
  • not_found (404): the operation or the resource does not exist.
  • internal (500): Harmony failed to handle the request.

Some operations return their own codes, listed below. Other errors use the status text as their code, such as bad_request for an invalid request body. New codes can be added, so handle codes you do not recognize by their HTTP status.

Status codes​

  • 400: the request is invalid. Fix it before sending it again.
  • 401, 403, 404: see the codes above.
  • 422 on PUT /api/v1/contacts/upsert: the contact can't be saved, and code says why. invalid_phone: the phone can't be read as a number. missing_dedup_field: the contact has none of the fields your Account deduplicates by, which is phone unless your Account chose others. dedup_key_too_long: those field values are too long.
  • 409 (conflict) on an external ID lookup: the lookup matched more than one contact. The body's contacts field lists them. To read one of them, use its Harmony id with GET /api/v1/contacts/{id}. The API can't list calls by Harmony id yet, so give each contact a unique external ID in your source system.
  • 5xx: Harmony failed to handle the request. Retrying with a delay is safe for reads, and for imports without assignmentOptions.workflowId. Retrying an upsert is safe unless your Account deduplicates by external ID and you sent externalId: null, which stores a duplicate, or you sent reEnroll and enforceCallNow, which calls the contact again. Otherwise the retry updates the contact the first attempt saved, and Harmony skips enrolling a contact the workflow already called. Don't retry an import that enrolls contacts automatically, since it can place two calls: first check what arrived with GET /api/v1/contacts?assignedWorkflowId=<workflowId>, then resend only the missing contacts.