Limitations
This page lists the constraints that apply to the current version of the developer API. Each entry describes the behaviour to expect and the approach an integration should take.
Read it alongside Getting Started and Authentication before designing an integration. Several of these constraints affect how requests are sequenced, which is easier to allow for up front than to retrofit.
Error Messages
An error response carries an HTTP status code and a message. The status code is the dependable part: it is documented in the reference and is stable for a given operation and outcome. The message is diagnostic. It does not always name the field that caused a validation failure, and its wording can change between releases.
An integration should branch on the status code and never on the text of a message. It should also log the full response body together with the request that produced it, which is the quickest way to work out why a call was rejected.
Where an operation returns a status code that does not match the outcome, it is noted under that resource below.
Response Schemas
Each operation in the reference documents its parameters, its request body, and the status codes it can return. Response bodies are not currently described, so a response's schema and example panels can be empty or show a generic object.
Confirm the shape of a response by calling the operation in a non-production environment, and ignore response fields the integration does not recognise, as described in Versioning.
Authentication
Every Authentication Failure Returns 403
A missing, malformed, expired, or revoked token, a token without the required scope,
and a token used against another organisation's path all return 403. The API does not
return 401, so the status code alone cannot tell an expired token from a missing
scope.
Request a new token once and retry the call once. If it fails again, check the key's
permissions and the {organisationId} in the path rather than retrying further. See
Cache and refresh the token.
The Token Response Is Not Standard OAuth
The token endpoint uses the OAuth 2.0 client credentials grant, but its response is the
standard response envelope with the token at data.accessToken. It has no
access_token, expires_in, or token_type field, so generic OAuth client libraries
cannot parse it without customisation. Read the expiry from the token's exp claim.
Editing a Key Signs Out Its Integrations
Any change to a key in the Admin app, even renaming it, invalidates every access token
already issued from it. Integrations recover by requesting a new token, but calls in
flight at the moment of the change return 403.
Agentic
Agent Config Is Only Available Once the Agent Is Live
The get agent config operation returns the configuration of the agent's live version.
An agent that has never gone live returns 409. Take the agent live in the Admin app
first, and treat a 409 as a configuration problem rather than a transient failure.
Sessions Cannot Be Deleted or Edited
There is no delete operation for sessions, and turns, tool calls, and events cannot be
edited or removed once appended. Send only what the transcript should keep, and keep
personal data out of content, input, and output unless the integration is allowed
to store it.
A Reused Session ID Overwrites the Session
The create session operation does not check whether sessionId is already in use. A
request that reuses an ID replaces that session's record. Omit sessionId to have one
generated, or generate a fresh UUID for each session.
Session Lists Are Not Paginated
The list sessions and reports operations return every matching session in one response.
Narrow reports with the from and to query parameters, which are Unix seconds and
default to the last 24 hours.
Timestamps Are in Seconds
Every timestamp, endedAt, from, and to value is a Unix time in seconds. Values
sent in milliseconds are stored as sent and are not converted, so they sort and display
incorrectly.
SCIM Configuration
Profile IDs Are Not Verified in Amazon Connect
routingProfileId and securityProfileIds, in both userMapping and
defaultUserMapping, are checked for format only: each value must be a well-formed
UUID. An ID that is well formed but does not correspond to a profile in the Amazon
Connect instance is accepted and saved, and the mismatch only becomes apparent when SCIM
next provisions a user.
Copy these IDs from Amazon Connect and confirm them before sending the configuration.
The Security Token Is Managed in the Admin App
The SCIM security token cannot be read or set through the API. Every other part of the configuration can be, but the token itself is generated in the NeonNow Admin app and copied into the identity provider from there. See External Provisioning.
Custom Schedules
Dates Are Added After the Schedule Is Created
The create operation accepts name, timezone, and description. Dates and status are
set by the update operation, so a schedule that contact flows can act on takes two
calls: create it, then update it with its scheduledDates and status.
An Updated Field Is Replaced in Full
The update operation works on whole fields. A field that is omitted is left unchanged, and a field that is supplied replaces its stored value completely.
This is most visible with scheduledDates: the array sent becomes the schedule's entire
set of dates, so a single date cannot be added, edited, or removed on its own. Read the
schedule, apply the change to the array it returns, and send that array back in full.
The last write wins, so updates to one schedule should be sequenced rather than issued
in parallel.
An Unknown Schedule Name Returns 500
An update that names a schedule which does not exist returns 500 rather than 404.
This is worth allowing for in retry logic: a 500 from this operation is not
necessarily transient, and retrying it will not help if the name is wrong.
Confirm the schedule exists with the get or list operation before updating it.
Operational Parameters
Table Columns Are Not Described in the Reference
Every TABLE parameter defines its own columns in its tableSchema, so the reference
describes a table row generically, as an object with arbitrary keys. Rows are still
validated when they are sent, and a row that does not match the parameter's columns is
rejected, but the reference cannot show what those columns are.
Read the parameter first and build rows from the tableSchema it returns.
Table Rows Are Replaced as a Complete Set
The replace table rows operation saves exactly the array it is sent, and any row not included is removed. Individual rows cannot be appended, edited, or deleted.
Read the current rows, apply the change locally, then send the complete set. As with schedule dates, the last write wins, so writes to one parameter should be sequenced.
Custom Type Values Are Not Enforced in Table Rows
Where a table column uses a custom type, row values are not checked against the values that type permits. A row can be saved with a value outside the list, and a contact flow reading that row will not resolve it as expected.
Validate row values against the list custom types operation before writing them.
An Update Must Send Both type and value
The update operation leaves omitted fields unchanged, with one exception: type and
value are validated as a pair. A request that changes value must send type as
well, even when the type is not changing.
Read the parameter first and send its current type alongside the new value.
Custom Types Use Separate Operations
The create and update operations for an operational parameter accept the built-in types
only: BOOLEAN, TEXT, NUMBER, PHONE_NUMBER, QUEUE, and TABLE. A parameter
typed with a custom type uses its own pair of operations:
POST /rest/v1/{organisationId}/{contactCenterId}/operational-parameter/custom
PATCH /rest/v1/{organisationId}/{contactCenterId}/operational-parameter/custom/{name}
They take the same fields as their built-in counterparts, so the only difference to account for is choosing the right path for the type being sent.
These operations do not check the value against the values the custom type permits, so validate it against the list custom types operation first.