Developer Docs Logo
API Requests

API Requests

Once your app has an access token from the OAuth installation flow, all CRM API calls follow the conventions described here. Read this before building any feature that calls the CRM API.


API Reference

The complete OpenAPI specification for all available endpoints that you can access with the Access Token can be found here. The OAuth endpoints specification is available here.

Base URL

All endpoints are under the https://dev.askyura.com/api/ prefix, with the exception of token exchange endpoint which uses https://api.askyura.com/api/ prefix.


Authentication

Include the workspace-scoped access token as a Bearer token on every request:

Authorization: Bearer {access_token}

The token is tied to a single workspace. Your app stores one token per workspace and uses the correct one for each call. See OAuth Flow for how to obtain and store the token.

Token expiry: If the CRM returns 401 Unauthorized, the token has expired or been revoked. Notify the agent to re-install the app. There is no refresh token mechanism.


Permission Scopes

Each endpoint requires one or more scopes. The agent grants these during installation. Your app declares the scopes it needs in the third-party app management dashboard.


Request Format

All request bodies must be JSON. Set the Content-Type header:

Content-Type: application/json

Response Structure

Single resource

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": { ... }
}

Collection / list

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [ ... ],
  "metadata": {
    "after": "7a30ad46-76a3-42df-9c0c-3fcf1b10f9d2",
    "before": "2db87b94-212f-4f6f-badd-03b6dd6a1a4e"
  }
}

List endpoints use cursor-based pagination. Pass after or before as query parameters using the cursors returned in the previous response's metadata:

GET /api/v1/conversations?limit=25&after=7a30ad46-76a3-42df-9c0c-3fcf1b10f9d2
Authorization: Bearer {access_token}
ParameterDescription
limitMaximum number of results per page (max 100, default varies by endpoint)
afterCursor pointing forward - returns the next page
beforeCursor pointing backward - returns the previous page

metadata.after is the cursor for the next page; metadata.before is the cursor for the previous page. When a cursor is an empty string or null, there are no more results in that direction.

Asynchronous operations

Several write operations are processed asynchronously and return 202 Accepted instead of 200 OK:

HTTP/1.1 202 Accepted
Content-Type: application/json

{
  "request_id": "ca9b5a07-1d77-46f3-9fa6-6c827db6ac3d"
}

Examples of async endpoints:

  • POST /v1/conversations - creates a conversation
  • POST /v1/conversations/{id}/messages - sends a message

For these calls:

  • Treat 202 as success, the action is queued and will be processed shortly.
  • Do not retry on 202. Retrying creates duplicate operations.

Delivery status via webhooks: After a message send is accepted, the CRM fires one of two webhook events once processing completes:

EventMeaning
message.sentThe message was delivered to the channel successfully.
message.failedDelivery failed (e.g. channel error, invalid recipient).

Both events include the original request_id in their data payload. Store the request_id from the 202 response and match it against the request_id field in the webhook to know whether a specific send succeeded or failed. See Webhooks: Message Delivery Status for payload details.

No content

Some status-update endpoints return 204 No Content with an empty body on success.

Error

All errors follow the same shape:

HTTP/1.1 4xx
Content-Type: application/json

{
  "message": "human-readable description of the error",
  "slug": "machine-readable-error-code"
}

slug is a machine-readable string (e.g., not-found, invalid-message-type, chats.sender-not-permitted).

Note: Slug values may change as the API evolves. The API is under rapid development, and slug stability is not guaranteed at this time, we may introduce a stable slug contract in a future release. For now, use slugs for logging and debugging. For branching logic in production code, prefer HTTP status codes instead.


HTTP Status Codes

CodeWhen it is returned
200 OKSuccessful read - resource or list returned
201 CreatedResource created synchronously
202 AcceptedWrite accepted for async processing
204 No ContentSuccess with no response body (e.g., status update)
400 Bad RequestInvalid input - missing fields, wrong types, constraint violation in the payload
401 UnauthorizedToken missing, invalid, or expired
403 ForbiddenToken lacks the required scope, or the principal is not permitted to perform the action
404 Not FoundThe resource does not exist or does not belong to the authenticated workspace
409 ConflictUniqueness or state constraint violated (e.g., contact already has an open conversation on this channel)

On this page