Dashly Docs

Docs

`/docs`

List docs

GET
/docs

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: docs: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"-updatedAt"
Value in"updatedAt""-updatedAt""createdAt""-createdAt""title""-title"
q?string

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

filter[clientVisible]?string

Exact match on clientVisible.

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

Exact match on portalScope.

filter[clientId]?string

Exact match on clientId.

filter[projectId]?string

Exact match on projectId.

Response Body

The requested page.

application/json
  1. response
data*array<>
meta*
Example Request
curl -X GET 'https://api.usedashly.com/v1/docs'
Example Response
{  "data": [    {      "id": "string",      "clientId": "string",      "projectId": "string",      "title": "string",      "body": "string",      "blocks": null,      "content": null,      "icon": "string",      "clientVisible": true,      "portalScope": "string",      "createdAt": "2019-08-24T14:15:22Z",      "updatedAt": "2019-08-24T14:15:22Z"    }  ],  "meta": {    "page": 0,    "perPage": 0,    "total": 0,    "totalPages": 0  }}

Create a doc

POST
/docs

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: docs: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
body?|null
blocks?array<unknown>
content?array<unknown>|

The BlockNote document (block array), the format the editor stores. Stock blocks include heading (props.level 1-3), paragraph, bulletListItem, numberedListItem, checkListItem, table and image. Project blocks read the doc's project (projectId) live wherever the doc is shown (editor, client portal, print page): { "type": "toc" } (table of contents from the headings), { "type": "projectRoadmap" }, { "type": "dealQuote", "props": { "scope": "all_one_shot" } } (scope: all_one_shot or a deal's public id), { "type": "recurring" } and { "type": "financialSummary" }. Without a projectId they show that their figures are unavailable. The printable page (browser PDF, agency members only) is /docs/{id}/print in the app. At most 400k characters serialized.

icon?|null
clientVisible?boolean
portalScope?string
Value in"internal""account""clients""all"
clientId?string|null
projectId?string|null
parentId?string|null
folderId?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/docs' \  -H 'Content-Type: application/json' \  -d '{  "title": "string"}'
Example Response
{  "data": {    "id": "string",    "clientId": "string",    "projectId": "string",    "title": "string",    "body": "string",    "blocks": null,    "content": null,    "icon": "string",    "clientVisible": true,    "portalScope": "string",    "createdAt": "2019-08-24T14:15:22Z",    "updatedAt": "2019-08-24T14:15:22Z"  }}

Retrieve a doc

GET
/docs/{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: docs: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/docs/string'
Example Response
{  "data": {    "id": "string",    "clientId": "string",    "projectId": "string",    "title": "string",    "body": "string",    "blocks": null,    "content": null,    "icon": "string",    "clientVisible": true,    "portalScope": "string",    "createdAt": "2019-08-24T14:15:22Z",    "updatedAt": "2019-08-24T14:15:22Z"  }}

Update a doc

PATCH
/docs/{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: docs: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
body?|null
blocks?array<unknown>
content?array<unknown>|

The BlockNote document (block array), the format the editor stores. Stock blocks include heading (props.level 1-3), paragraph, bulletListItem, numberedListItem, checkListItem, table and image. Project blocks read the doc's project (projectId) live wherever the doc is shown (editor, client portal, print page): { "type": "toc" } (table of contents from the headings), { "type": "projectRoadmap" }, { "type": "dealQuote", "props": { "scope": "all_one_shot" } } (scope: all_one_shot or a deal's public id), { "type": "recurring" } and { "type": "financialSummary" }. Without a projectId they show that their figures are unavailable. The printable page (browser PDF, agency members only) is /docs/{id}/print in the app. At most 400k characters serialized.

icon?|null
clientVisible?boolean
portalScope?string
Value in"internal""account""clients""all"
clientId?string|null
projectId?string|null
parentId?string|null
folderId?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/docs/string' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": {    "id": "string",    "clientId": "string",    "projectId": "string",    "title": "string",    "body": "string",    "blocks": null,    "content": null,    "icon": "string",    "clientVisible": true,    "portalScope": "string",    "createdAt": "2019-08-24T14:15:22Z",    "updatedAt": "2019-08-24T14:15:22Z"  }}

Delete a doc

DELETE
/docs/{id}

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

Required scope: docs: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/docs/string'
Example Response
Empty

List available actions

GET
/docs/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: docs: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/docs/actions'
Example Response
{  "data": [    {      "name": "string",      "label": "string",      "description": "string",      "target": "item",      "readOnly": true,      "path": "string",      "input": {}    }  ]}

Read who may see a doc

GET
/docs/{id}/actions/get-access

Whether the doc's client sees it in its portal (null for a doc with no client), its public link token (null when off), and each of the agency's providers (partners with an active share on one of its projects) with granted.

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

Required scope: docs: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/docs/string/actions/get-access'
Example Response
{  "data": null}

Read who may see a doc

POST
/docs/{id}/actions/get-access

Whether the doc's client sees it in its portal (null for a doc with no client), its public link token (null when off), and each of the agency's providers (partners with an active share on one of its projects) with granted.

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

Required scope: docs: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/docs/string/actions/get-access' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": null}

Set who may see a doc

POST
/docs/{id}/actions/set-access

The client's portal (clientVisible, a doc with a client only - doc_access_client_only otherwise; absent = unchanged) and exactly the providers who read it read-only in their space (keys from get-access; one who works on none of the agency's projects is refused, doc_provider_not_on_agency). Independent: turning the portal off clears no provider.

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

Required scope: docs: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
clientVisible?boolean
providers?array<>
Itemsitems <= 100
Default[]

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/docs/string/actions/set-access' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": null}
POST
/docs/{id}/actions/set-sharing

Turns the doc's public read-only link on, returning the token (the page is /d/) - re-enabling an active link rotates it - or off, revoking the token.

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

Required scope: docs: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
enabled*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/docs/string/actions/set-sharing' \  -H 'Content-Type: application/json' \  -d '{  "enabled": true}'
Example Response
{  "data": null}
POST
/docs/{id}/actions/set-association

What the doc belongs to: a client (public id) and optionally one of its projects, or no client (the agency's) and optionally an internal project. A project of another client is refused (project_other_client). Changing the client files the doc in that client's folder and takes it (and its sub-pages) out of the client portal.

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

Required scope: docs: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
clientId*|null
projectId?|
Defaultnull

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/docs/string/actions/set-association' \  -H 'Content-Type: application/json' \  -d '{  "clientId": "string"}'
Example Response
{  "data": null}

Move to a folder

POST
/docs/{id}/actions/move

Files the doc in the given folder (a public id from /v1/doc-folders), or at the root when folderId is null or absent.

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

Required scope: docs: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
folderId?|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/docs/string/actions/move' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": null}

Move within the tree

POST
/docs/{id}/actions/relocate

Places the doc under another doc - it becomes a sub-page and follows that doc's folder - into a folder when only folderId is given, or at the root when both are null. A move into its own descendants is refused, and portal visibility is never widened.

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

Required scope: docs: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
parentId?|null
folderId?|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/docs/string/actions/relocate' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": null}
POST
/docs/{id}/actions/pin

Puts the doc on the front row of the agency's Resources page (pinned: true, newest pin first) or takes it back (false). A Resources concept: the Documents page shows no front row. Agency-side only: the portal never reads it.

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

Required scope: docs: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
pinned*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/docs/string/actions/pin' \  -H 'Content-Type: application/json' \  -d '{  "pinned": true}'
Example Response
{  "data": null}