For AI agents: markdown of this page — /docs-content-en/infra/access-tokens/resource-url.md documentation index — /llms.txt

Signed resource URL

POST /v1/infra/servers/:id/access-tokens/:tokenId/resource-url

Issues a GET/HEAD URL for one resource of a private application: CSS, an image or a font. It works without a browser Gateway session and does not open other application paths. Anyone possessing the URL can read the selected resource until expiry or parent token revocation. Sign only content you intend to distribute to widget recipients.

Requires the key that manages the server and an existing api-bearer token created by that key through Mint a token, including the required audience approval. No new token record is created; the parent's lifetime and approved audience are not extended. Development-team, external-collaborator and Cowork keys cannot call this operation. Check section availability before calling.

Known link-preview fetchers receive a local card for a public application or a neutral page for a private application; the Gateway does not proxy their request through the tunnel even when it carries a resource URL. A resource URL does not override this policy.

Parameters

Parameter In Type Required Description
Parameterid Inpath Typestring Requiredyes DescriptionServer ID from List servers
ParametertokenId Inpath Typestring Requiredyes Descriptiondata.id of an existing minted api-bearer token

Request body

Field Type Required Description
Fieldpath Typestring Requiredyes DescriptionAbsolute ASCII path of 2–1024 characters, for example /widget/style.css. The root / is not allowed. Allowed characters: letters, digits, /, ., _, ~, -. No query, fragment, %, // or ./.. segments. /robots.txt, /_gw, /tunnel and every path inside /_gw/ or /tunnel/ are reserved
FieldttlSeconds Typeinteger Requiredno Description1–2592000 seconds, default 86400. Actual expiry is capped by the parent

Extra body fields are rejected with 400 INVALID_RESOURCE_REQUEST.

Examples

Run on your application server. Do not send the key or user session to the browser.

curl — personal key

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/access-tokens/TOKEN_ID/resource-url" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"path":"/widget/style.css","ttlSeconds":86400}'

curl — OAuth application

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/access-tokens/TOKEN_ID/resource-url" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"path":"/widget/style.css","ttlSeconds":86400}'

JavaScript — personal key

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/access-tokens/TOKEN_ID/resource-url', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ path: '/widget/style.css', ttlSeconds: 86400 }),
})
const result = await res.json()
if (!res.ok || result.success !== true) {
  throw new Error(result.error?.code ?? `HTTP_${res.status}`)
}
const { data } = result
// Use data.url in the widget and replace it before data.expiresAt.

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/access-tokens/TOKEN_ID/resource-url', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    Authorization: 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ path: '/widget/style.css', ttlSeconds: 86400 }),
})
const result = await res.json()
if (!res.ok || result.success !== true) {
  throw new Error(result.error?.code ?? `HTTP_${res.status}`)
}
const { data } = result
// Use data.url in the widget and replace it before data.expiresAt.

Response fields

Field Type Description
Fieldsuccess Typeboolean Descriptiontrue
Fielddata Typeobject DescriptionSigned URL and its expiry
Fielddata.url Typestring DescriptionResource URL carrying __resource; preserve the entire URL
Fielddata.expiresAt Typestring (ISO 8601) DescriptionURL expiry, capped by the parent

Response example

Captured from a local HTTP call; the deployment hostname and credential are masked.

JSON
{
  "success": true,
  "data": {
    "url": "https://app-example.vibecode.bitrix24.com/widget/style.css?__resource=SIGNED_RESOURCE_JWT",
    "expiresAt": "2026-10-10T14:11:21.000Z"
  }
}

Error response example

400 — ttlSeconds is zero:

JSON
{
  "success": false,
  "error": {
    "code": "INVALID_RESOURCE_REQUEST",
    "message": "Expected path and optional integer ttlSeconds; no extra fields."
  }
}

Errors

HTTP Code Action
HTTP400 CodeINVALID_RESOURCE_REQUEST ActionFix the body, field types or TTL
HTTP400 CodeINVALID_RESOURCE_PATH ActionUse a canonical ASCII resource path
HTTP400 CodeWRONG_TOKEN_MODE ActionUse an api-bearer parent
HTTP400 CodeSERVER_NO_SUBDOMAIN ActionUse a server with a subdomain
HTTP401 CodeMISSING_API_KEY ActionNo API key was supplied through X-Api-Key or a supported Authorization: Bearer scheme
HTTP401 CodeINVALID_API_KEY ActionThe authentication key is not recognized
HTTP401 CodeKEY_INACTIVE ActionThe requesting API key is no longer active
HTTP401 CodeKEY_EXPIRED ActionThe requesting API key has expired; this is distinct from resource URL expiry
HTTP401 CodeNO_PORTAL ActionA non-management key has no portal binding
HTTP401 CodeCOWORK_CHAT_KEY_INACTIVE ActionThe parent device key behind a Cowork chat key is no longer usable
HTTP401 CodeWRONG_AUTH_SCHEME ActionAn OAuth application key was sent as a Bearer session: put the key in X-Api-Key and the session in Authorization: Bearer
HTTP401 CodeINVALID_SESSION ActionThe supplied OAuth session is invalid or expired
HTTP401 CodeTOKEN_EXPIRED ActionThe OAuth user token expired and its refresh failed; re-authorization is required
HTTP401 CodeTOKEN_INVALID ActionWhen the partner AI plane is enabled, its supplied token is unknown or expired
HTTP401 CodeKEY_REVOKED ActionThe partner credential behind the AI plane token is revoked
HTTP402 CodeACCOUNT_FROZEN ActionThe key owner’s account is frozen. With wallet-debt scoping disabled, the shared API-key guard refuses this call before its handler. Follow error.topupUrl to resolve the balance; this status alone does not authorize repeating a prior write.
HTTP403 CodeKEY_BLOCKED ActionThe current or a recorded previous token issuer is blocked
HTTP403 CodeTOKEN_OWNER_MISMATCH ActionUse the key that owns both parent and server
HTTP403 CodeWRITE_BLOCKED_READONLY_KEY ActionA read-only key cannot perform this write.
HTTP403 CodeINFRA_FORBIDDEN_FOR_COWORK_KEY ActionUse the key that manages the server outside Cowork
HTTP403 CodePORTAL_COLLABORATOR_KEY_OUT_OF_SCOPE ActionA development-team key cannot sign resource URLs
HTTP403 CodeEXTERNAL_COLLABORATOR_KEY_OUT_OF_SCOPE ActionAn external-collaborator key cannot sign resource URLs
HTTP403 CodeIP_NOT_ALLOWED ActionThe caller IP is outside the key allowlist.
HTTP403 CodeOWNER_BLOCKED ActionThe key owner is blocked.
HTTP403 CodeOWNER_DELETED ActionThe key owner was deleted.
HTTP403 CodePORTAL_SUSPENDED ActionThe bound portal is suspended.
HTTP403 CodePORTAL_DELETED ActionThe bound portal was deleted.
HTTP403 CodePORTAL_BLOCKED ActionThe bound portal is blocked.
HTTP403 CodeMANAGEMENT_KEY_NO_ENTITY_ACCESS ActionThe management key lacks the portal binding or entity authority required by this call.
HTTP403 CodeAGENT_MAINTENANCE_KEY_OUT_OF_SCOPE ActionThe maintenance key route list does not include this operation.
HTTP403 CodeAPP_API_KEY_OUT_OF_SCOPE ActionThe application key route list does not include this operation.
HTTP403 CodeWAITLIST_PENDING ActionThe key owner has not been activated.
HTTP403 CodeSESSION_APP_MISMATCH ActionThe OAuth session belongs to another application.
HTTP403 CodePLANE_FORBIDDEN ActionThe partner key does not allow this AI plane.
HTTP403 CodeSYSTEM_FORBIDDEN ActionThe partner key does not allow this AI system.
HTTP403 CodeSCOPE_FORBIDDEN ActionThe partner AI plane forbids this route.
HTTP403 CodeCONNECT_COMPANY_DERIVED_TOKEN_FORBIDDEN ActionA company connection key cannot manage derived tokens.
HTTP403 CodeCOWORK_READONLY ActionThe Cowork seat is read-only.
HTTP403 CodeGALAXY_DISABLED ActionGalaxy operations are disabled for this portal.
HTTP404 CodeNOT_FOUND ActionThe parent token was not found or the server's portal has been deactivated
HTTP404 CodeSERVER_NOT_FOUND ActionCheck the server ID
HTTP410 CodeALREADY_REVOKED ActionMint a new approved parent token
HTTP410 CodeTOKEN_EXPIRED ActionMint a new approved parent with a valid expiry
HTTP429 CodeQUOTA_EXCEEDED ActionAPI billing is enabled with a nonzero overage price: the daily free quota is exhausted and the PREPAY balance is not positive. Top up the balance. error.quota and error.used report counts; X-RateLimit-Quota, X-RateLimit-Used and X-RateLimit-Remaining report the quota, usage and zero remainder. This refusal does not promise Retry-After or X-RateLimit-Scope
HTTP429 CodeCALLER_RATE_LIMITED ActionThe shared key or user request limit. Wait for the number of seconds specified in Retry-After; X-RateLimit-Scope identifies the refusing layer
HTTP503 CodeFEATURE_DISABLED ActionThe access-token section is unavailable
HTTP503 CodeACCOUNT_PENDING_ERASURE ActionThe key owner is pending erasure or being erased. Header Retry-After: 3600.
HTTP503 CodeSERVICE_DISABLED ActionThe partner AI plane or its quota-readiness service is disabled. No Retry-After is promised for this refusal.
HTTP503 Codeuser_self_deletion_pending ActionThe API key owner scheduled self-deletion. The token plugin refuses the call before its handler. Header Retry-After: 604800.

When reading a resource, an altered, expired or revoked URL, another method, query or path returns 401 BH_RESOURCE_URL_INVALID. Resource signatures are not accepted as Bearer or cookie sessions. If the application tunnel is disconnected, the Gateway returns neutral JSON 503 BH_RESOURCE_UNAVAILABLE: the URL does not wake the server or expose the owner's billing state. Common errors: Errors.

The Gateway checks the parent token on every resource read. A network failure, timeout or malformed authority response returns neutral 503 BH_RESOURCE_UNAVAILABLE; confirmed revocation returns 401 BH_RESOURCE_URL_INVALID. The request is refused without falling back to a browser session or public access.

Known specifics

Main-page widget with PORTAL access

  1. Create one parent api-bearer token with the required lifetime and audience approval.
  2. Sign the stylesheet and each image/font path separately through this operation.
  3. Use the signed stylesheet URL as WIDGET_PARAMS.style when registering through landing.repowidget.register. Use the corresponding signed URLs in CSS url(...), HTML images and previews.
  4. Renew the URLs and update widget registration before expiresAt. Relative image paths do not inherit the stylesheet URL's signature and remain private.
  5. Revoke the parent to stop every derived URL early.

Ordinary application URLs remain protected under PORTAL. The Gateway does not rewrite HTML/CSS or automatically sign dependencies. Resource requests do not create cookies or forward user identity or X-Vibe-Authorization; the application must serve the resource without a personal session. Responses carry Cache-Control: no-store and Referrer-Policy: no-referrer.

See also