Auth header
Authorization: Bearer tsk_live_…The key needssites:write
Request body
domainstringrequireddisplayNamestringrequiredregionstringrequiredOne of
EU,US
Example request
curl -X POST "https://app.tagsentry.ai/api/v1/sites" \ -H "Authorization: Bearer tsk_live_…" \ -H "Content-Type: application/json" \ -d '{"domain":"silverpine.example","displayName":"Silverpine Supply","region":"EU"}'Response 201
idstringrequiredThe site's id. This is what every /v1/sites/{siteId} path takes.
accountIdstringrequireddomainstringrequireddisplayNamestringrequiredregionstringrequiredWhere this site's consent records and tag events are stored. Fixed at creation and never editable -- data residency is not a setting you can flip.
One of
EU,USstatusstringrequiredOne of
pending,active,archivedarchivedAtstring | nullrequiredcreatedAtstringrequiredISO-8601 timestamp, UTC.
updatedAtstringrequiredISO-8601 timestamp, UTC.
Example response
{ "id": "3f6c1b8e-2d4a-4c7e-9a51-0b8f2e6d7c10", "accountId": "3f6c1b8e-2d4a-4c7e-9a51-0b8f2e6d7c10", "domain": "silverpine.example", "displayName": "Silverpine Supply", "region": "EU", "status": "pending", "archivedAt": "2026-09-26T14:02:00.000Z", "createdAt": "2026-09-26T14:02:00.000Z", "updatedAt": "2026-09-26T14:02:00.000Z"}More about this endpoint
The domain is not checked for ownership here and the site is usable immediately -- verification is a separate state that gates acting outward on the domain's behalf, never the site's existence. region is fixed at creation and can never be changed: it decides where this site's consent records and tag events are stored.
Errors400 · 401 · 403 · 409 · 500
400The request did not validate against this operation's schema.401Missing, malformed, unknown, revoked or expired API key. These are deliberately indistinguishable in the response -- distinguishing them would confirm to a caller that a token was once real.403The key authenticated but does not carry the scope(s) this operation requires, or (`domain_not_verified`) the site's domain is not verified, so its consent records are not released.409The request conflicts with existing state.500Something failed on our side. The requestId in the body is what to quote.
Every error has the same body: { error: { code, message, requestId } }.
From the OpenAPI document, version 2026-08-26. Raw OpenAPI