Dashly Docs

Saved keywords

`/seo-keywords`

List saved keywords

GET
/seo-keywords

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: seo-keywords: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""keyword""-keyword""volume""-volume"
q?string

Case-insensitive "contains", across: keyword.

filter[clientId]?string

Exact match on clientId.

filter[source]?string

Exact match on source.

filter[intent]?string

Exact match on intent.

filter[tag]?string

Only the keywords carrying this tag (case aside).

Response Body

The requested page.

application/json
  1. response
data*array<>
meta*
Example Request
curl -X GET 'https://api.usedashly.com/v1/seo-keywords'
Example Response
{  "data": [    {      "id": "string",      "clientId": "string",      "keyword": "string",      "tags": null,      "volume": 0,      "difficulty": 0,      "intent": "string",      "source": "string",      "metricsAt": "2019-08-24T14:15:22Z",      "createdAt": "2019-08-24T14:15:22Z",      "updatedAt": "2019-08-24T14:15:22Z"    }  ],  "meta": {    "page": 0,    "perPage": 0,    "total": 0,    "totalPages": 0  }}

Create a saved keyword

POST
/seo-keywords

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: seo-keywords: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
keyword*string
Length1 <= length <= 200
tags?array<>
Itemsitems <= 20
clientId*string
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/seo-keywords' \  -H 'Content-Type: application/json' \  -d '{  "keyword": "string",  "clientId": "string"}'
Example Response
{  "data": {    "id": "string",    "clientId": "string",    "keyword": "string",    "tags": null,    "volume": 0,    "difficulty": 0,    "intent": "string",    "source": "string",    "metricsAt": "2019-08-24T14:15:22Z",    "createdAt": "2019-08-24T14:15:22Z",    "updatedAt": "2019-08-24T14:15:22Z"  }}

Retrieve a saved keyword

GET
/seo-keywords/{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: seo-keywords: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/seo-keywords/string'
Example Response
{  "data": {    "id": "string",    "clientId": "string",    "keyword": "string",    "tags": null,    "volume": 0,    "difficulty": 0,    "intent": "string",    "source": "string",    "metricsAt": "2019-08-24T14:15:22Z",    "createdAt": "2019-08-24T14:15:22Z",    "updatedAt": "2019-08-24T14:15:22Z"  }}

Update a saved keyword

PATCH
/seo-keywords/{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: seo-keywords: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
tags?array<>
Itemsitems <= 20

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/seo-keywords/string' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": {    "id": "string",    "clientId": "string",    "keyword": "string",    "tags": null,    "volume": 0,    "difficulty": 0,    "intent": "string",    "source": "string",    "metricsAt": "2019-08-24T14:15:22Z",    "createdAt": "2019-08-24T14:15:22Z",    "updatedAt": "2019-08-24T14:15:22Z"  }}

Delete a saved keyword

DELETE
/seo-keywords/{id}

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

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

List available actions

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

Research keywords

POST
/seo-keywords/actions/research

Researches keywords for a client in its rank tracking market (France/French by default): kind: ideas returns ideas around the seed keywords in query; kind: domain the keywords the domain in query ranks for, with position and url. Each row has volume (monthly searches), difficulty (0-100), intent and cpc (USD), up to 100 rows. An answer is kept 30 days per agency, question and market and costs nothing when served from that cache (cached: true); otherwise it takes 5 checks from the rank tracking's monthly allowance. Needs the rank_tracking add-on. Saves nothing: POST the rows you keep to seo-keywords.

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

Required scope: seo-keywords: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
clientId*string
Length1 <= length
kind*string
Value in"ideas""domain"
query*|array<>

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/seo-keywords/actions/research' \  -H 'Content-Type: application/json' \  -d '{  "clientId": "string",  "kind": "ideas",  "query": "string"}'
Example Response
{  "data": null}
POST
/seo-keywords/actions/measure-ai-volume

Measures how often the client's saved keywords are asked of AI tools each month (aiVolume on each seo-keywords row), for the ones not measured in the last 30 days, 100 at most per call, in the client's rank tracking market. Takes 5 checks from the rank tracking's monthly allowance; nothing is counted when DataForSEO refuses. Needs the rank_tracking add-on. Returns how many keywords were measured.

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

Required scope: seo-keywords: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
clientId*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/seo-keywords/actions/measure-ai-volume' \  -H 'Content-Type: application/json' \  -d '{  "clientId": "string"}'
Example Response
{  "data": null}