xYago APIv1

Errors

Errors use standard HTTP status codes and always the same JSON body. Branch on error.code, which is stable; message is informative and may change.

HTTP/1.1 409 Conflict
Content-Type: application/json
X-Request-Id: req_7f3a9c2e5b1d4f60

{
  "error": {
    "code": "external_id_already_exists",
    "message": "external_id is already assigned to another employee of the company."
  }
}

All codes

The reference lists the codes each endpoint can return. New codes may be added in v1 (always with a consistent HTTP status): handle an unknown code by its status.

HTTPCodeMeaning and what to do
400invalid_cursorThe cursor is not valid (tampered with or from another listing). Restart the listing without a cursor.
401invalid_api_keyThe API key is missing, invalid, revoked or expired.
403api_disabledThe product (areas, employees...) is not enabled in the admin panel for the key's environment (live or test).
403endpoint_disabledAn administrator disabled this specific endpoint in the panel.
403insufficient_scopeThe API key lacks the scope the endpoint requires (e.g. employees:write).
403ip_not_allowedThe source IP is not in the product's IP allowlist.
403new_recipients_pausedxYago paused the sender's sends to new recipients (too many phones without xYago). Recipients that already got messages keep working. Contact xYago.
403verify_pausedxYago paused Verify for the sender (too many phones without xYago). Verifications already started can still be checked. Contact xYago.
404not_foundThe resource does not exist or belongs to another company (never distinguished).
404sender_not_foundThe sender_id is not a sender of your account.
404template_not_foundThe sender has no template with that name.
404recipient_not_on_xyagoPOST /verify/start: the phone does not use xYago. Nothing was sent and nothing will be retried: send the code through your other channel (e.g. SMS).
409area_already_existsAn area with that name already exists under the same parent.
409external_id_already_existsThe external_id is already assigned to another employee of the company.
409external_id_in_progressAnother request is creating an employee with that external_id right now. Retry in a few seconds (look it up by external_id first).
409employee_already_existsAn employee with that phone_number already exists in the company.
409email_already_registeredThe email is already used by another employee.
409document_number_already_existsThe document_number is already used by another employee of the company.
409vacation_already_decidedThe request was already approved or rejected.
409vacation_overlapThe employee already has approved vacations in that range.
409time_entry_overlapThe entry overlaps another entry of the employee in the company.
409sender_not_approvedThe sender is not approved by xYago yet (in live only approved senders can send).
409sender_suspendedxYago suspended the sender (or the account). Contact xYago.
409template_not_approvedThe template is not approved (in sandbox a draft one also works).
409template_pausedxYago paused the template (e.g. after user complaints). It cannot be used until xYago reactivates it; contact xYago.
409idempotency_key_reusedThat Idempotency-Key was already used with a different body. Use a new key for each different send.
409undeliverableThe message cannot be delivered to this recipient. Do not retry.
409verification_expiredThe code expired (10 minutes). Start a new verification.
409max_attempts_reachedThe verification's 5 attempts are used up. Start a new one.
409verification_not_pendingThe verification no longer accepts codes: it was already verified (single use), superseded by a newer one (canceled) or could not be sent (failed).
409sandbox_number_existsThe number is already a confirmed test number.
422validation_errorThe body or parameters do not match the schema (required field, format, unknown field...). message names the field.
422invalid_parent_idparent_id does not reference an active area of the company.
422invalid_employee_dataxYago rejected the employee data. Check the fields.
422employee_has_no_jobTried to change the job of an employee who has no job in the company.
422invalid_employee_idemployee_id does not reference an employee of the company.
422invalid_vacationxYago rejected the vacation request.
422vacation_type_not_configuredThe company has no vacation time-off type configured in xYago.
422vacation_requires_documentThe company requires a supporting document for vacations; they cannot be requested through the API.
422invalid_date_rangeInvalid from..to range: from after to or longer than 31 days.
422invalid_time_rangeThe entry ends in the future.
422invalid_time_entryxYago rejected the time entry.
422invalid_phoneto is not a valid E.164 phone number (at least 10 digits).
422template_variables_mismatchThe number of variables does not match the template's variables_count.
422invalid_variablesA variable is longer than 256 characters or contains a link.
422invalid_button_variablesA button_variables value for a url button with a variable is missing, one is not expected (the button has no variable) or it is invalid (text, max. 200 characters).
422sandbox_recipient_not_allowedWith an xy_test_ key you can only send to the test numbers confirmed in the panel.
422invalid_messagexYago rejected the message content.
429rate_limitedThe API key exceeded its per-minute request limit or, on POST /messages, a sender sending cap (messages per minute, per recipient per day, new recipients per day) or, in Verify, a code cap (wait between codes, per phone, per sender) or the wrong-codes-per-hour cap. Wait the Retry-After seconds.
500internal_errorUnexpected xYago error. Retry with backoff; if it persists, contact support with the X-Request-Id.
502upstream_errorAn internal xYago service failed or timed out. Retry with backoff (for writes, check first whether they were applied).
503limits_unavailableSending limits cannot be checked right now; for safety nothing is sent. Retry with backoff and the same Idempotency-Key.
503messaging_not_configuredMessaging is temporarily unavailable. Contact support.
503import_queue_unavailableThe import could not be queued. Try again later.

What to retry

StatusRetry?
400, 401, 403, 404, 409, 422No: fix the request or the configuration. Exception: 409 external_id_in_progress (retry in a few seconds).
429Yes, after the Retry-After seconds.
500, 502, 503, network errors / timeoutsYes, with exponential backoff (e.g. 1 s, 2 s, 4 s... at most 5 attempts). For writes, first check whether they were applied (see idempotency).

Validation errors

422 validation_error names the failing field in message as field: reason (several separated by ; ). Unknown fields are rejected too: sending company_id when creating an employee returns 422, because the company comes from the API key.

{
  "error": {
    "code": "validation_error",
    "message": "phone_number: String should match pattern '^\\+[1-9][0-9]{6,14}$'; company_id: Extra inputs are not permitted"
  }
}

When contacting support

Include the response's X-Request-Id, method and path, time (UTC) and environment (live/test). Never send the API key.