Dashly Docs

Tickets

`/tickets`

List tickets

GET
/tickets

One page of records, newest first unless you say otherwise, with the total count in meta so you know how far to paginate.

Required scope: tickets:read.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Query Parameters

page?integer

1-based. meta.totalPages says how many there are.

Range1 <= value
Default1
per_page?integer

Rows per page. A value above 200 returns 400 - never a silent clamp.

Range1 <= value <= 200
Default50
sort?string

Prefix with - for descending. An undeclared sort returns 400.

Default"-createdAt"
Value in"createdAt""-createdAt""dueDate""-dueDate""priority""-priority""status""-status""resolvedAt""-resolvedAt"
q?string

Case-insensitive "contains", across: title, description.

filter[status]?string

Exact match on status.

filter[priority]?string

Exact match on priority.

Value in"low""medium""high""urgent"
filter[difficulty]?string

Exact match on difficulty.

filter[scope]?string

Exact match on scope.

Value in"client""agency""internal"
filter[clientVisible]?string

Exact match on clientVisible.

Value in"true""false"
filter[clientId]?string

Exact match on clientId.

filter[projectId]?string

Exact match on projectId.

filter[parentId]?string

Exact match on parentId.

filter[assigneeId]?string

Exact match on assigneeId.

filter[categoryId]?string

Exact match on categoryId.

filter[teamId]?string

Exact match on teamId.

filter[milestoneId]?string

Exact match on milestoneId.

filter[cycleId]?string

Exact match on cycleId.

filter[open]?string

true for tickets not yet in a terminal column of the agency's workflow, false for the finished ones. Reads the agency's own columns, never the literal done.

Value in"true""false"
filter[archived]?string

false (the default) leaves archived tickets out; true lists only them. Put away with bulk-update { archived: true }.

Value in"true""false"
filter[withinProjectId]?string

A project's public id: the tickets of that project AND of its sub-projects. filter[projectId] reads one project (or one sub-project) only.

Response Body

The requested page.

application/json
  1. response
data*array<>
meta*
Example Request
curl -X GET 'https://api.usedashly.com/v1/tickets'
Example Response
{  "data": [    {      "id": "string",      "title": "string",      "description": "string",      "scope": "client",      "status": "string",      "priority": "low",      "clientVisible": true,      "dueDate": "2019-08-24T14:15:22Z",      "estimateMinutes": 0,      "difficulty": "string",      "commitRef": "string",      "resolvedAt": "2019-08-24T14:15:22Z",      "resolvedById": "string",      "archivedAt": "2019-08-24T14:15:22Z",      "clientId": "string",      "projectId": "string",      "parentId": "string",      "assigneeId": "string",      "categoryId": "string",      "teamId": "string",      "milestoneId": "string",      "cycleId": "string",      "createdAt": "2019-08-24T14:15:22Z",      "customFields": {}    }  ],  "meta": {    "page": 0,    "perPage": 0,    "total": 0,    "totalPages": 0  }}

Create a ticket

POST
/tickets

Links are given as the target's public id (clientId: "hsbftmp3f5"); the API resolves them server-side. Fields the database requires but the interface decides for you are filled in the same way here.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
title*string
Length1 <= length <= 300
description?string|null
scope?string

client or agency. internal is a deprecated alias of agency, stored as agency.

Value in"client""agency""internal"
status?string
Length1 <= length <= 40
priority?string
Value in"low""medium""high""urgent"
clientVisible?boolean
dueDate?string|null
estimateMinutes?|null
difficulty?|null
commitRef?|null
clientId?string|null
projectId?string|null
parentId?string|null
assigneeId?string|null
categoryId?string|null
customFields?
milestoneId?string|null
cycleId?string|null
createdAt?string

When this actually happened, for an import. Past dates only; defaults to now. updatedAt follows it unless the body sets one.

Formatdate-time

Response Body

Created. The body is the new record, as a read would return it.

application/json
  1. response
data*
Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets' \  -H 'Content-Type: application/json' \  -d '{  "title": "string"}'
Example Response
{  "data": {    "id": "string",    "title": "string",    "description": "string",    "scope": "client",    "status": "string",    "priority": "low",    "clientVisible": true,    "dueDate": "2019-08-24T14:15:22Z",    "estimateMinutes": 0,    "difficulty": "string",    "commitRef": "string",    "resolvedAt": "2019-08-24T14:15:22Z",    "resolvedById": "string",    "archivedAt": "2019-08-24T14:15:22Z",    "clientId": "string",    "projectId": "string",    "parentId": "string",    "assigneeId": "string",    "categoryId": "string",    "teamId": "string",    "milestoneId": "string",    "cycleId": "string",    "createdAt": "2019-08-24T14:15:22Z",    "customFields": {}  }}

Retrieve a ticket

GET
/tickets/{id}

The full record, custom fields included when the resource carries them. A record from another agency is a 404, not a 403 - its existence is not ours to confirm.

Required scope: tickets:read.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The record's public id (hsbftmp3f5), as returned in the id field. An internal UUID returns 404.

Response Body

Found.

application/json
  1. response
data*
Example Request
curl -X GET 'https://api.usedashly.com/v1/tickets/string'
Example Response
{  "data": {    "id": "string",    "title": "string",    "description": "string",    "scope": "client",    "status": "string",    "priority": "low",    "clientVisible": true,    "dueDate": "2019-08-24T14:15:22Z",    "estimateMinutes": 0,    "difficulty": "string",    "commitRef": "string",    "resolvedAt": "2019-08-24T14:15:22Z",    "resolvedById": "string",    "archivedAt": "2019-08-24T14:15:22Z",    "clientId": "string",    "projectId": "string",    "parentId": "string",    "assigneeId": "string",    "categoryId": "string",    "teamId": "string",    "milestoneId": "string",    "cycleId": "string",    "createdAt": "2019-08-24T14:15:22Z",    "customFields": {}  }}

Update a ticket

PATCH
/tickets/{id}

A partial update: only the fields you send change. One exception - customFields is replaced wholesale, not merged, so sending it with a single key clears the others. Read the record, merge, then write.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The record's public id (hsbftmp3f5), as returned in the id field. An internal UUID returns 404.

Request Body

application/json
  1. body
title?string
Length1 <= length <= 300
description?string|null
scope?string

client or agency. internal is a deprecated alias of agency, stored as agency.

Value in"client""agency""internal"
status?string
Length1 <= length <= 40
priority?string
Value in"low""medium""high""urgent"
clientVisible?boolean
dueDate?string|null
estimateMinutes?|null
difficulty?|null
commitRef?|null
clientId?string|null
projectId?string|null
parentId?string|null
assigneeId?string|null
categoryId?string|null
customFields?
milestoneId?string|null
cycleId?string|null

Response Body

Updated. The body is the record as it now stands.

application/json
  1. response
data*
Example Request
curl -X PATCH 'https://api.usedashly.com/v1/tickets/string' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": {    "id": "string",    "title": "string",    "description": "string",    "scope": "client",    "status": "string",    "priority": "low",    "clientVisible": true,    "dueDate": "2019-08-24T14:15:22Z",    "estimateMinutes": 0,    "difficulty": "string",    "commitRef": "string",    "resolvedAt": "2019-08-24T14:15:22Z",    "resolvedById": "string",    "archivedAt": "2019-08-24T14:15:22Z",    "clientId": "string",    "projectId": "string",    "parentId": "string",    "assigneeId": "string",    "categoryId": "string",    "teamId": "string",    "milestoneId": "string",    "cycleId": "string",    "createdAt": "2019-08-24T14:15:22Z",    "customFields": {}  }}

Delete a ticket

DELETE
/tickets/{id}

Permanent. The audit log keeps the trace; the record does not come back.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The record's public id (hsbftmp3f5), as returned in the id field. An internal UUID returns 404.

Response Body

Deleted. Empty body.

Example Request
curl -X DELETE 'https://api.usedashly.com/v1/tickets/string'
Example Response
Empty

List available actions

GET
/tickets/actions

Every verb this resource answers to, with its target and the JSON Schema of its body - the same contracts this document describes, readable at runtime.

Required scope: tickets:read.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Response Body

The available verbs.

application/json
  1. response
data*array<>
Example Request
curl -X GET 'https://api.usedashly.com/v1/tickets/actions'
Example Response
{  "data": [    {      "name": "string",      "label": "string",      "description": "string",      "target": "item",      "readOnly": true,      "path": "string",      "input": {}    }  ]}

Add a dependency

POST
/tickets/{id}/actions/add-dependency

Declares that this ticket is blocked by another one (dependsOnId). Refuses self-blocking and an immediate reverse dependency.

Does what the dashboard's addTicketDependencyAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
dependsOnId*string
Length1 <= length

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/add-dependency' \  -H 'Content-Type: application/json' \  -d '{  "dependsOnId": "string"}'
Example Response
{  "data": null}

Remove a dependency

POST
/tickets/{id}/actions/remove-dependency

Removes the "blocked by" link between this ticket and the ticket named by dependsOnId.

Does what the dashboard's removeTicketDependencyAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
dependsOnId*string
Length1 <= length

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/remove-dependency' \  -H 'Content-Type: application/json' \  -d '{  "dependsOnId": "string"}'
Example Response
{  "data": null}

Attach a file

POST
/tickets/{id}/actions/upload-attachment

Adds an attachment to this ticket: base64 content, 5 MB maximum once decoded, stored in the private bucket and visible in the dashboard straight away.

Does what the dashboard's uploadAttachmentAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
fileName*string
Length1 <= length <= 200
contentType?string
Lengthlength <= 120
data*string
Match^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$
Formatbase64
Lengthlength <= 6990508

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/upload-attachment' \  -H 'Content-Type: application/json' \  -d '{  "fileName": "string",  "data": "string"}'
Example Response
{  "data": null}

Delete an attachment

POST
/tickets/{id}/actions/delete-attachment

Deletes this ticket's attachment with the given filename, row and stored file alike. Refused when two of the ticket's attachments share that name.

Does what the dashboard's deleteAttachmentAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
fileName*string
Length1 <= length <= 200

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/delete-attachment' \  -H 'Content-Type: application/json' \  -d '{  "fileName": "string"}'
Example Response
{  "data": null}
GET
/tickets/{id}/actions/widget-context

For a ticket filed from the review widget: each remark behind it with its page (URL, title, release), the reviewer's environment (browser and version, OS, device, viewport, language, raw user-agent), the zone pointed at (selector, text, coordinates), the page's errors and a screenshot URL valid 10 minutes. remarks is empty for a ticket that did not come from the widget.

Reads the same data as the in-app listWidgetFeedbackForTicket - same implementation. Changes nothing; also answers GET with the same fields as query parameters.

Required scope: tickets:read.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Response Body

The figures.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X GET 'https://api.usedashly.com/v1/tickets/string/actions/widget-context'
Example Response
{  "data": null}
POST
/tickets/{id}/actions/widget-context

For a ticket filed from the review widget: each remark behind it with its page (URL, title, release), the reviewer's environment (browser and version, OS, device, viewport, language, raw user-agent), the zone pointed at (selector, text, coordinates), the page's errors and a screenshot URL valid 10 minutes. remarks is empty for a ticket that did not come from the widget.

Reads the same data as the in-app listWidgetFeedbackForTicket - same implementation. Changes nothing; also answers GET with the same fields as query parameters.

Required scope: tickets:read.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/widget-context' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": null}
POST
/tickets/{id}/actions/link-object

Creates a relation between this record and a target object (targetType plus the target's public targetId) in the relation graph. Linking the same pair twice does nothing.

Does what the dashboard's linkObjectAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
targetType*string
Value in"account""contact""project""ticket""deal""user""proposal"
targetId*string
Length1 <= length <= 60

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/link-object' \  -H 'Content-Type: application/json' \  -d '{  "targetType": "account",  "targetId": "string"}'
Example Response
{  "data": null}
POST
/tickets/{id}/actions/unlink-object

Removes the relation between this record and the target object in the relation graph. Unlinking a pair that was never linked does nothing. A deal/project pair is unlinked like unlink-project on the deal: the change is audited, so the key must be attached to a user (403 with reason key_not_attached otherwise).

Does what the dashboard's unlinkObjectAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
targetType*string
Value in"account""contact""project""ticket""deal""user""proposal"
targetId*string
Length1 <= length <= 60

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/unlink-object' \  -H 'Content-Type: application/json' \  -d '{  "targetType": "account",  "targetId": "string"}'
Example Response
{  "data": null}
POST
/tickets/{id}/actions/merge

Merges the listed tickets (sourceIds, public ids) into this one, in one transaction: this ticket keeps its title, their descriptions are appended under a heading each, and their comments, attachments, subtasks, assignees (added after this ticket's own), links, dependencies, time, relations and history move here; each source is archived with a comment and a relation pointing here. A source of another client needs confirmClientChange: true; a source this ticket is a subtask of is refused; dryRun: true answers the counts without writing. Re-running the same merge changes nothing (alreadyMerged).

Does what the dashboard's mergeTicketsAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
sourceIds*array<>
Items1 <= items <= 50
confirmClientChange?boolean
dryRun?boolean

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/merge' \  -H 'Content-Type: application/json' \  -d '{  "sourceIds": [    "string"  ]}'
Example Response
{  "data": null}
POST
/tickets/{id}/actions/set-assignees

Replaces the ticket's assignees with assigneeIds (member ids from /v1/members), in order; the first becomes the ticket's assigneeId. An empty list unassigns it. At most 10.

Does what the dashboard's setTicketAssigneesAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
assigneeIds*array<>
Itemsitems <= 10

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/set-assignees' \  -H 'Content-Type: application/json' \  -d '{  "assigneeIds": [    "string"  ]}'
Example Response
{  "data": null}
POST
/tickets/actions/bulk-assignees

On at most 200 tickets at once, in one write: add puts the member after the people already there, remove takes them off (the next person becomes the ticket's assigneeId), replace makes them the only assignee — or unassigns every ticket with assigneeId: null. Agency members only.

Does what the dashboard's bulkEditTicketAssigneesAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
itemIds*array<>
Items1 <= items <= 200
mode*string
Value in"add""remove""replace"
assigneeId*|null

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/actions/bulk-assignees' \  -H 'Content-Type: application/json' \  -d '{  "itemIds": [    "string"  ],  "mode": "add",  "assigneeId": "string"}'
Example Response
{  "data": null}
GET
/tickets/{id}/actions/assignees

Everyone the ticket is assigned to, in order: assigneeIds (member ids from /v1/members) and each person's name. The first is the ticket's assigneeId.

Reads the same data as the in-app listTicketAssignees - same implementation. Changes nothing; also answers GET with the same fields as query parameters.

Required scope: tickets:read.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Response Body

The figures.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X GET 'https://api.usedashly.com/v1/tickets/string/actions/assignees'
Example Response
{  "data": null}
POST
/tickets/{id}/actions/assignees

Everyone the ticket is assigned to, in order: assigneeIds (member ids from /v1/members) and each person's name. The first is the ticket's assigneeId.

Reads the same data as the in-app listTicketAssignees - same implementation. Changes nothing; also answers GET with the same fields as query parameters.

Required scope: tickets:read.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/assignees' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": null}
POST
/tickets/{id}/actions/set-client-assignees

Replaces the ticket's client-side assignees: memberIds (members of the ticket's client portal, from the client-assignees read's candidates), in order, and/or clientSide: true for the client organisation as a whole. A member of another client is refused (not_a_client_member). Assigning makes the ticket visible in the client's portal: pass makeClientVisible: true when it is not yet. The newly assigned are notified (portal bell; email for a signed client). Not counted as agency workload.

Does what the dashboard's setTicketClientAssigneesAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
memberIds*array<>
Itemsitems <= 10
clientSide?boolean
Defaultfalse
makeClientVisible?boolean
Defaultfalse

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/set-client-assignees' \  -H 'Content-Type: application/json' \  -d '{  "memberIds": [    "string"  ]}'
Example Response
{  "data": null}
GET
/tickets/{id}/actions/client-assignees

Who on the client's side the ticket is assigned to — clientSide (the organisation) and members — and candidates, every member of the ticket's client portal it may be assigned to. clientId is null for a ticket without client.

Reads the same data as the in-app listTicketClientAssignees - same implementation. Changes nothing; also answers GET with the same fields as query parameters.

Required scope: tickets:read.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Response Body

The figures.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X GET 'https://api.usedashly.com/v1/tickets/string/actions/client-assignees'
Example Response
{  "data": null}
POST
/tickets/{id}/actions/client-assignees

Who on the client's side the ticket is assigned to — clientSide (the organisation) and members — and candidates, every member of the ticket's client portal it may be assigned to. clientId is null for a ticket without client.

Reads the same data as the in-app listTicketClientAssignees - same implementation. Changes nothing; also answers GET with the same fields as query parameters.

Required scope: tickets:read.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/client-assignees' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": null}
GET
/tickets/{id}/actions/sentry-issues

The Sentry issues the ticket names, each read live from the agency's Sentry (title, project, status, event and user counts, first and last seen, link). When Sentry is not connected or cannot answer, an issue comes back with issue: null, its href when one is known, and error (not_connected, other_org, unauthorized, not_found, upstream...).

Reads the same data as the in-app readTicketSentryIssues - same implementation. Changes nothing; also answers GET with the same fields as query parameters.

Required scope: tickets:read.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Response Body

The figures.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X GET 'https://api.usedashly.com/v1/tickets/string/actions/sentry-issues'
Example Response
{  "data": null}
POST
/tickets/{id}/actions/sentry-issues

The Sentry issues the ticket names, each read live from the agency's Sentry (title, project, status, event and user counts, first and last seen, link). When Sentry is not connected or cannot answer, an issue comes back with issue: null, its href when one is known, and error (not_connected, other_org, unauthorized, not_found, upstream...).

Reads the same data as the in-app readTicketSentryIssues - same implementation. Changes nothing; also answers GET with the same fields as query parameters.

Required scope: tickets:read.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/sentry-issues' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": null}
POST
/tickets/{id}/actions/add-sentry-issues

Adds Sentry issues after the ticket's own: issue URLs (sentry.io, us.sentry.io, de.sentry.io), short ids (WEB-1) or numeric ids. One value that is none of these refuses the whole call (sentry_issue_invalid, details.invalid). When the ticket is resolved, its issues are resolved in Sentry.

Does what the dashboard's addTicketSentryIssuesAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
issues*array<>
Items1 <= items <= 10

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/add-sentry-issues' \  -H 'Content-Type: application/json' \  -d '{  "issues": [    "string"  ]}'
Example Response
{  "data": null}
POST
/tickets/{id}/actions/remove-sentry-issue

Removes one issue by the key the read returns (WEB-1, 4512345678). An unknown key changes nothing. The issue itself is untouched in Sentry.

Does what the dashboard's removeTicketSentryIssueAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
key*string
Length1 <= length <= 100

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/remove-sentry-issue' \  -H 'Content-Type: application/json' \  -d '{  "key": "string"}'
Example Response
{  "data": null}
POST
/tickets/{id}/actions/set-sentry-issues

Replaces the ticket's Sentry issues with issues, in that order; [] clears them. Same values and refusals as add-sentry-issues.

Does what the dashboard's setTicketSentryIssues does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
issues*array<>
Itemsitems <= 10

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/set-sentry-issues' \  -H 'Content-Type: application/json' \  -d '{  "issues": [    "string"  ]}'
Example Response
{  "data": null}

Update several tickets

POST
/tickets/actions/bulk-update

Applies the same change - status, priority, difficulty, category, assignee, archived - to at most 200 tickets in a single write. The status is checked against the agency's workflow columns.

Does what the dashboard's bulkUpdateWorkItemsAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
itemIds*array<>
Items1 <= items <= 200
status?string
Length1 <= length <= 40
priority?string
Value in"low""medium""high""urgent"
difficulty?|null
archived?boolean
categoryId?|null
assigneeId?|null

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/actions/bulk-update' \  -H 'Content-Type: application/json' \  -d '{  "itemIds": [    "string"  ]}'
Example Response
{  "data": null}
POST
/tickets/{id}/actions/set-content

Replaces the ticket's body (a BlockNote document) and rewrites its plain-text description at the same time - the one the portal, the e-mails and search read.

Does what the dashboard's setTicketContentAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Path Parameters

id*string

The public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
content*array<unknown>
Itemsitems <= 2000

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/string/actions/set-content' \  -H 'Content-Type: application/json' \  -d '{  "content": [    null  ]}'
Example Response
{  "data": null}
POST
/tickets/actions/save-workflow

Replaces the agency's workflow columns wholesale - between 2 and 12, at least one terminal and one non-terminal. Tickets left in a deleted column move to the first non-terminal column, and the response says how many.

Does what the dashboard's saveWorkflowAction does - same implementation, so the two cannot diverge.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Request Body

application/json
  1. body
columns*array<>
Items2 <= items <= 12

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/actions/save-workflow' \  -H 'Content-Type: application/json' \  -d '{  "columns": [    {      "label": "string",      "color": "slate",      "isDone": true    },    {      "label": "string",      "color": "slate",      "isDone": true    }  ]}'
Example Response
{  "data": null}

Reset the workflow

POST
/tickets/actions/reset-workflow

Restores the five columns the product ships with, moving tickets left in a deleted column to the first non-terminal one.

Does what the dashboard's resetWorkflowAction does - same implementation, so the two cannot diverge. Takes no body.

Required scope: tickets:write.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.

Header Parameters

Idempotency-Key?string

A value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.

Length8 <= length <= 255

Response Body

Done.

application/json
  1. response
data*unknown

The action's result; its shape depends on the verb.

Example Request
curl -X POST 'https://api.usedashly.com/v1/tickets/actions/reset-workflow'
Example Response
{  "data": null}