Skip to Content
APIEndpointsCreate prompt

Create prompt

Starts monitoring a question. The prompt is created, consumes plan allowance, and begins executing immediately across the engines the brand tracks.

Requires the write:prompts scope, and the workspace must be enabled for API writes.

POST /v1/brands/{brand_id}/prompts

This one costs money. Every other write on this API edits configuration. Creating a prompt consumes one active-prompt slot per market and triggers a run against every engine, so a single call produces real usage. Budget for it the way you would a job you queued, not the way you would a config change.

Authorization

HeaderTypeRequired
AuthorizationBearer asky_sk_…required
Idempotency-Keystringrequired

Path parameters

ParameterTypeRequiredDescription
brand_iduuidrequiredFrom List brands

Query parameters

None.

Any parameter you pass returns 400 invalid_request naming the offending key.

Body

application/json

FieldTypeRequiredDescription
textstring, 1–500 charsrequiredThe question to monitor
country_codesstring[], up to 20optionalTwo-letter markets like US, SE. Defaults to the brand’s market. Each one consumes a slot
topic_iduuid | nulloptionalOmit for uncategorised
tag_idsuuid[], up to 50optionalTags to apply to the new prompt

There is no is_active. Prompts cannot be paused, in the app or here, so every prompt created is active and counts toward your allowance.

Request

curl --request POST \ --url 'https://api.askylabs.com/v1/brands/242546de-4cee-4a7d-952e-f6aa60c63ef8/prompts' \ --header 'Authorization: Bearer <api-key>' \ --header 'Idempotency-Key: <unique-per-attempt>' \ --header 'Content-Type: application/json' \ --data '{"text":"What is the best AI visibility tracker?","country_codes":["US","SE"]}'

Response

{ "data": { "prompt": { "id": "b71e3c04-95af-4d28-8a16-5c0f7e2d1a93", "prompt_text": "What is the best AI visibility tracker?", "topic_id": null, "funnel_stages": [], "is_active": true }, "country_codes": ["US", "SE"], "quota": { "limit": 200, "used": 148, "remaining": 52 } }, "request_id": "req_0f3a71be29c44d85b6ce" }

Response fields

FieldTypeDescription
data.prompt.iduuidrequired. Use it with Get prompt
data.prompt.prompt_textstringrequired
data.prompt.topic_iduuid | nullrequired
data.prompt.funnel_stagesstring[]required. Empty until the classifier runs
data.prompt.is_activebooleanrequired. Always true
data.country_codesstring[]required. The markets actually used, after defaulting
data.quota.limitinteger | nullrequired. Your plan’s active-prompt limit, null if unlimited
data.quota.usedintegerrequired. Including the prompt you just created
data.quota.remainingintegerrequired. What is left after this call
request_idstringrequired. Also returned as the x-request-id header

Errors

StatusCodeWhen
400invalid_requestUnknown field, missing or over-long text, a bad country code, or a topic_id / tag_ids not on this brand
401invalid_tokenThe key is missing, malformed, or does not exist
403insufficient_scopeThe key does not carry write:prompts
403plan_requiredThis workspace is not enabled for API writes
403quota_exceededThe request would exceed your active-prompt allowance. Nothing is created
404not_foundThe brand does not exist, or this key is not allowed to reach it
409conflictThis brand already tracks a prompt with that text
429rate_limitedOver 60 requests per minute
503service_unavailableYour allowance could not be checked. Nothing is created. Retry shortly

quota_exceeded and plan_required are both 403 and mean different things. plan_required means your plan does not include API writes at all, and the fix is an upgrade. quota_exceeded means it does and you have used your slots, where deleting prompts you no longer track may be enough.

Notes

Quota is per market, not per prompt. A prompt targeting five countries takes five slots. The check runs before anything is written and covers the whole request, so a prompt is never half-created in two of the three markets you asked for.

If the allowance cannot be checked, nothing is created. A 503 here means the check itself was unavailable and we refused rather than guessing. Retry; it is transient.

The prompt exists immediately; its data does not. Funnel stage, search-demand tier and the first results come from background work. Reading it back straight away returns empty funnel_stages and null metrics. That is expected, not a failure.

Duplicates are rejected. Text that already exists for the brand, ignoring case and whitespace, returns 409 conflict rather than creating a second copy.

Prompts created here are marked api. The provenance is distinct from prompts added by hand in the app, so a surprising bill can be traced to the integration that caused it.

Idempotency-Key is required, and matters more here than elsewhere. Reuse it when retrying and the original response is replayed rather than a second prompt being created and a second slot spent. See Idempotency.

Last updated on