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/jsonResponse 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}| Parameter | Description |
|---|---|
limit | Maximum number of results per page (max 100, default varies by endpoint) |
after | Cursor pointing forward - returns the next page |
before | Cursor 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 conversationPOST /v1/conversations/{id}/messages- sends a message
For these calls:
- Treat
202as 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:
| Event | Meaning |
|---|---|
message.sent | The message was delivered to the channel successfully. |
message.failed | Delivery 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
| Code | When it is returned |
|---|---|
200 OK | Successful read - resource or list returned |
201 Created | Resource created synchronously |
202 Accepted | Write accepted for async processing |
204 No Content | Success with no response body (e.g., status update) |
400 Bad Request | Invalid input - missing fields, wrong types, constraint violation in the payload |
401 Unauthorized | Token missing, invalid, or expired |
403 Forbidden | Token lacks the required scope, or the principal is not permitted to perform the action |
404 Not Found | The resource does not exist or does not belong to the authenticated workspace |
409 Conflict | Uniqueness or state constraint violated (e.g., contact already has an open conversation on this channel) |