Dashly Docs

AI visibility settings

`/geo-settings`

GET
/geo-settings

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: geo-settings: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""updatedAt""-updatedAt""brand""-brand"
q?string

Case-insensitive "contains", across: brand, domain.

filter[clientId]?string

Exact match on clientId.

filter[enabled]?string

Exact match on enabled.

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

Exact match on frequency.

filter[country]?string

Exact match on country.

filter[locale]?string

Exact match on locale.

filter[portalVisible]?string

Exact match on portalVisible.

Value in"true""false"

Response Body

The requested page.

application/json
  1. response
data*array<>
meta*
Example Request
curl -X GET 'https://api.usedashly.com/v1/geo-settings'
Example Response
{  "data": [    {      "id": "string",      "clientId": "string",      "brand": "string",      "domain": "string",      "aliases": null,      "competitors": null,      "country": "string",      "locale": "string",      "engines": null,      "models": null,      "frequency": "string",      "portalVisible": true,      "enabled": true,      "activatedAt": "2019-08-24T14:15:22Z",      "lastRunAt": "2019-08-24T14:15:22Z",      "lastError": "string",      "createdAt": "2019-08-24T14:15:22Z",      "updatedAt": "2019-08-24T14:15:22Z"    }  ],  "meta": {    "page": 0,    "perPage": 0,    "total": 0,    "totalPages": 0  }}
POST
/geo-settings

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: geo-settings: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
brand*string
Length1 <= length <= 120
domain?|null
aliases?array<>
Itemsitems <= 25
competitors?array<>
Itemsitems <= 25
country?string
Length2 <= length <= 2
locale?string
Value in"fr""en"
engines*array<>
Items1 <= items
models?array<>
frequency?string
Value in"daily""weekly""monthly"
portalVisible?boolean
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/geo-settings' \  -H 'Content-Type: application/json' \  -d '{  "brand": "string",  "engines": [    "chatgpt"  ],  "clientId": "string"}'
Example Response
{  "data": {    "id": "string",    "clientId": "string",    "brand": "string",    "domain": "string",    "aliases": null,    "competitors": null,    "country": "string",    "locale": "string",    "engines": null,    "models": null,    "frequency": "string",    "portalVisible": true,    "enabled": true,    "activatedAt": "2019-08-24T14:15:22Z",    "lastRunAt": "2019-08-24T14:15:22Z",    "lastError": "string",    "createdAt": "2019-08-24T14:15:22Z",    "updatedAt": "2019-08-24T14:15:22Z"  }}
GET
/geo-settings/{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: geo-settings: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/geo-settings/string'
Example Response
{  "data": {    "id": "string",    "clientId": "string",    "brand": "string",    "domain": "string",    "aliases": null,    "competitors": null,    "country": "string",    "locale": "string",    "engines": null,    "models": null,    "frequency": "string",    "portalVisible": true,    "enabled": true,    "activatedAt": "2019-08-24T14:15:22Z",    "lastRunAt": "2019-08-24T14:15:22Z",    "lastError": "string",    "createdAt": "2019-08-24T14:15:22Z",    "updatedAt": "2019-08-24T14:15:22Z"  }}
PATCH
/geo-settings/{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: geo-settings: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
brand?string
Length1 <= length <= 120
domain?|null
aliases?array<>
Itemsitems <= 25
competitors?array<>
Itemsitems <= 25
country?string
Length2 <= length <= 2
locale?string
Value in"fr""en"
engines?array<>
Items1 <= items
models?array<>
frequency?string
Value in"daily""weekly""monthly"
portalVisible?boolean

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/geo-settings/string' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": {    "id": "string",    "clientId": "string",    "brand": "string",    "domain": "string",    "aliases": null,    "competitors": null,    "country": "string",    "locale": "string",    "engines": null,    "models": null,    "frequency": "string",    "portalVisible": true,    "enabled": true,    "activatedAt": "2019-08-24T14:15:22Z",    "lastRunAt": "2019-08-24T14:15:22Z",    "lastError": "string",    "createdAt": "2019-08-24T14:15:22Z",    "updatedAt": "2019-08-24T14:15:22Z"  }}

List available actions

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

Starts a capture of the client's AI visibility now, in the background, exactly like the dashboard's capture button: every active question is asked on every configured engine and model, which SPENDS the agency's AI-visibility allowance. Requires the module to be switched on for the client (never possible through a key), the AI-visibility add-on, at least one active question, and a key whose owner holds reports.manage. Answers at once with status: started; the capture takes a few minutes. Read the result with GET /v1/clients/{id}/actions/ai-visibility, and a later refusal (credits exhausted) in lastError of this configuration.

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

Required scope: geo-settings: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

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/geo-settings/string/actions/capture'
Example Response
{  "data": null}
POST
/geo-settings/{id}/actions/edit-competitors

Adds and/or removes competitor brand names on this AI visibility configuration without resending the list (add, remove; case is ignored, a name already present keeps its spelling). At most 25 competitors. Returns the resulting competitors. Changes nothing on any invoice; the next capture measures share of voice against the new list.

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

Required scope: geo-settings: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
add?array<>
Itemsitems <= 25
remove?array<>
Itemsitems <= 25

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/geo-settings/string/actions/edit-competitors' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": null}
POST
/geo-settings/{id}/actions/edit-aliases

Adds and/or removes other spellings that count as the client's brand (add, remove; case is ignored). At most 25 aliases. Returns the resulting aliases.

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

Required scope: geo-settings: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
add?array<>
Itemsitems <= 25
remove?array<>
Itemsitems <= 25

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/geo-settings/string/actions/edit-aliases' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "data": null}