Create a private integrator for the current tenant Provision a tenant-private integration plus its first API…
POST /api/configuration/operator/integrators/private
Success: 201 Created
- Products: Operator (
FOH) - Features: Front of House Generic Access (
FOHGENERIC)
Overview
Creates a tenant specific private integrator and its first API key in one call. Unlike a global integrator, this integrator belongs to the calling tenant's environment: no other tenant can see it, and it never appears in the Gladstone-curated global catalogue.
The full plaintext API key is in the apiKey field of this response and is returned exactly once. Gladstone keeps only a hash of it plus an 8-character prefix, so no endpoint and no support process can recover it. Write it to your secret store before you do anything else with the response. If you lose it, your only route back is to renew the key, which invalidates the old one.
The tenant is taken from your token, not from the request body. If the environment cannot be resolved from your token the call fails with 400 and nothing is created.
This call is not idempotent, and names are not unique. A retry after a timeout creates a second integrator with a second live API key — both of which work. Before retrying, list your private integrators and check whether the first attempt succeeded.
The integrator is created with isGlobal false, isActive true and environmentId set to your environment; none of those are settable.
Endpoint
POST {base_url}/api/configuration/operator/integrators/private
{base_url} is the environment URL issued to your integration. See Authenticating with Gladstone APIs.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | The display name of the integrator, for your own identification within the tenant. Maximum 255 characters, and it may not be empty or whitespace-only. Names are not unique — nothing stops you creating two integrators called the same thing, so track them by id. |
description | string | No | Free-text note about what this integration is for. No length limit. Omit it, or send null, to leave it blank. |
origin | string | Yes | The exact web origin your integration calls from, for example https://app.example.com. Maximum 255 characters, may not be empty. Enforced at token-issue time: a token request that sends an Origin header must match this value or it is rejected with 401. The comparison ignores case and a trailing slash and is otherwise exact — no wildcards, and only one origin per integrator. A token request with no Origin header skips the check, so this protects browser callers rather than server-to-server ones. |
logoUrl | string | No | Absolute URL of a logo for the integration. Maximum 500 characters. Omit it, or send null, to have none. Stored as given; never fetched or validated. |
isBillable | boolean | No | Whether usage under this integrator is chargeable. Becomes a billable claim on every token issued from its key. Defaults to true for private integrators when omitted — the opposite of the global default. |
allowedScopes | string | No | The features this integrator may reach, as a JSON array encoded into a string — for example "[\"FOHGENERIC\"]". Use the feature codes listed in the features line of each endpoint page. At token-issue time each entry in the array becomes both a features claim and a products claim; API routes require both, so an integrator with no scopes receives a token that every route rejects with 403. If the string is not valid JSON, nothing reports it and the resulting token carries no scope claims at all — you get no error here and no error at token issue, only 403s afterwards. Omitting the field has the same effect. |
canRead | boolean | No | Whether this integrator may perform read operations. Becomes a can_read claim on every token issued from its key. Defaults to false when omitted. Send true explicitly. |
canWrite | boolean | No | Whether this integrator may perform write operations. Becomes a can_write claim on every token issued from its key. Defaults to false when omitted, as with canRead. |
canDelete | boolean | No | Whether this integrator may perform delete operations. Becomes a can_delete claim on every token issued from its key. Defaults to false when omitted, as with canRead. |
rateLimitPerMinute | integer (int32) | No | The per-minute request budget recorded against the integrator. Must be 0 or greater; a negative value is rejected with 400. Defaults to 0 when omitted. |
rateLimitPerHour | integer (int32) | No | The per-hour request budget recorded against the integrator. Must be 0 or greater; a negative value is rejected with 400. Defaults to 0 when omitted. |
Sample request
curl -X POST '{base_url}/api/configuration/operator/integrators/private' \
-H 'Authorization: Bearer {accessToken}' \
-H 'X-Use-SSO: true' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"description": "string",
"origin": "string",
"logoUrl": "string",
"isBillable": true,
"allowedScopes": "string",
"canRead": true,
"canWrite": true,
"canDelete": true,
"rateLimitPerMinute": 1,
"rateLimitPerHour": 1
}'Response fields
| Field | Type | Description |
|---|---|---|
apiKey | string | The full plaintext API key, in the form gsk_sV_ followed by 32 random characters. Returned exactly once, here. Only a hash and the first 8 characters are kept, so this value cannot be recovered by any means — persist it to your secret store immediately. A fresh key can only be obtained by renewing, which revokes this one. |
apiKeyPrefix | string | The first 8 characters of apiKey, safe to display and log. This is the only part of the key that later reads return, so use it to identify which key a system is holding without exposing the secret. |
id | integer (int32) | The integer identifier the system allocated for the new integrator. You cannot choose it. Use it to update, list, renew the key for, or delete this integrator. |
name | string | The integrator's display name as stored — echoes what you sent. |
description | string | The description as stored, or null if you did not send one. |
origin | string | The allowed origin as stored. Token requests carrying a mismatched Origin header are rejected with 401. |
logoUrl | string | The logo URL as stored, or null if you did not send one. |
isGlobal | boolean | Always false here — the integrator is private to your tenant and invisible to others and to the global catalogue. |
isBillable | boolean | Whether usage under this integrator is chargeable — echoes what you sent, or true if you omitted it. Carried as a billable claim on every token issued from its key. |
environmentId | integer (int32) | The identifier of your tenant's environment, taken from your token rather than from the request. It is what binds the integrator to your tenant, and what allows tokens minted from its key to carry tenant claims and reach tenant-scoped endpoints. |
allowedScopes | string | The scope string as stored. Check it is a valid JSON array before you rely on the key: an unparseable or empty value produces tokens with no features or products claims, which every API route rejects with 403. |
canRead | boolean | Whether the integrator may read — echoes what you sent, or false if omitted. Carried as a can_read claim on tokens issued from its key. |
canWrite | boolean | Whether the integrator may write — echoes what you sent, or false if omitted. Carried as a can_write claim. |
canDelete | boolean | Whether the integrator may delete — echoes what you sent, or false if omitted. Carried as a can_delete claim. |
rateLimitPerMinute | integer (int32) | The per-minute budget as stored — echoes what you sent, or 0 if omitted. |
rateLimitPerHour | integer (int32) | The per-hour budget as stored — echoes what you sent, or 0 if omitted. |
isActive | boolean | Always true on creation. It becomes false when the integrator is deleted — a deleted integrator is kept but marked inactive, and its active key is revoked. |
createdOn | string (date-time) | UTC timestamp the integrator was created, set for you. |
modifiedOn | string (date-time) | UTC timestamp of the last update. Null on a freshly created integrator. |
Sample response
{
"apiKey": "string",
"apiKeyPrefix": "string",
"id": 12345,
"name": "string",
"description": "string",
"origin": "string",
"logoUrl": "string",
"isGlobal": true,
"isBillable": true,
"environmentId": 12345,
"allowedScopes": "string",
"canRead": true,
"canWrite": true,
"canDelete": true,
"rateLimitPerMinute": 1,
"rateLimitPerHour": 1,
"isActive": true,
"createdOn": "2026-08-14T19:00:00Z",
"modifiedOn": "2026-08-14T19:00:00Z"
}Errors
| Status | Meaning | When |
|---|---|---|
400 | Bad request | name or origin is missing, empty or whitespace-only, or a rate limit is negative. The body is a validation problem document (application/problem+json) with an errors map naming the offending field. |
400 | Bad request | The tenant environment could not be resolved from your token — the body is the plain string Could not resolve tenant environment. Nothing is created. |
500 | Internal server error | An unexpected server-side failure. The body is empty. Because the integrator and its key are created in two separate steps, treat a 500 as "state unknown" and list your private integrators before retrying. |