gateway HTTP contracts
Supported HTTP operations, source validators, SDK companions and explicit OpenAPI schema limits.
Supported HTTP operations, source validators, SDK companions and explicit OpenAPI schema limits.
These HTTP contracts are an explicit supported subset, not the whole Core API. Prefer the SDK when it exposes the operation. Authentication schemes are alternatives, not interchangeable tokens. Use the documented consumer context or CLI exchange; never send a raw maker credential as a consumer token. Read the owning guides for permissions, confirmation and asynchronous completion.
POST /management/businesses/{businessId}/auth/context-token
OpenAPI uses GenericObject or GenericObjectArray here and does not fully specify the HTTP contract. These are documentation placeholders, not permission to send arbitrary fields. SDK signatures describe normalized SDK inputs and outputs, not exact wire response envelopes. Source validators specify structural inputs; route authorization and semantic checks still apply.
{
"limitation": "OpenAPI uses GenericObject or GenericObjectArray here and does not fully specify the HTTP contract. These are documentation placeholders, not permission to send arbitrary fields. SDK signatures describe normalized SDK inputs and outputs, not exact wire response envelopes. Source validators specify structural inputs; route authorization and semantic checks still apply.",
"requestValidator": {
"name": "contextTokenSchema",
"source": "apps/core/src/validation/management-billing-schemas.ts#L93",
"declaration": "export const contextTokenSchema = z.object({\n externalOrgId: z.string().min(1).max(255),\n actorType: z.enum([\"org\", \"user\"]).optional(),\n actorId: z.string().optional(),\n ttlSeconds: z.number().int().min(60).max(86400).default(3600),\n});"
},
"responseEvidence": {
"name": "MintContextTokenSuccess",
"source": "apps/core/src/services/management/mint-context-token.ts#L31",
"declaration": "type MintContextTokenSuccess = {\n ok: true;\n data: { token: string; expiresAt: string };\n};"
},
"note": "No public SDK method. Use the management credential context in the owning gateway guide. HTTP success is { data: { token, expiresAt } }; ok:true is an internal service discriminator and is not part of the HTTP body."
}
OpenAPI metadata (incomplete):
{
"operationId": "createContextToken",
"summary": "Create a signed context token (fsc_) for gateway auth",
"tags": [
"Management Billing"
],
"security": [
{
"browserBearerAuth": []
},
{
"cliUserSessionBearerAuth": []
},
{
"makerTokenAccessBearerAuth": []
}
],
"x-farthershore-agent-operations": [
"auth.context.issue"
],
"x-farthershore-agent-target": {
"kind": "path",
"targetKind": "business",
"parameter": "businessId"
},
"x-farthershore-agent-retry": [
{
"operationKey": "auth.context.issue",
"kind": "no_automatic_retry",
"keyRequired": false,
"enforcement": "reconcile_before_repeat",
"responseSemantics": "outcome_may_be_unknown"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
},
"responses": {
"200": {
"description": "Signed context token",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": false,
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"additionalProperties": false,
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"details": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": false,
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"additionalProperties": false,
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"details": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": false,
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"additionalProperties": false,
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"details": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": false,
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"additionalProperties": false,
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"details": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
}
}
}
}
}
POST /portal/businesses/{businessId}/me/gateway-token
OpenAPI uses GenericObject or GenericObjectArray here and does not fully specify the HTTP contract. These are documentation placeholders, not permission to send arbitrary fields. SDK signatures describe normalized SDK inputs and outputs, not exact wire response envelopes. Source validators specify structural inputs; route authorization and semantic checks still apply.
{
"limitation": "OpenAPI uses GenericObject or GenericObjectArray here and does not fully specify the HTTP contract. These are documentation placeholders, not permission to send arbitrary fields. SDK signatures describe normalized SDK inputs and outputs, not exact wire response envelopes. Source validators specify structural inputs; route authorization and semantic checks still apply.",
"requestValidator": {
"name": "gatewayTokenSchema",
"source": "apps/core/src/validation/portal-schemas.ts#L124",
"declaration": "export const gatewayTokenSchema = z.object({}).strict().default({});"
},
"responseEvidence": {
"name": "GatewayContextToken",
"source": "packages/farthershore-js/src/types.ts#L886",
"declaration": "export interface GatewayContextToken {\n /** Short-lived `fsc_` bearer accepted by the Gateway for this subscriber. */\n token: string;\n /** ISO timestamp when the token expires. */\n expiresAt: string;\n}"
},
"note": "The hosted SDK's client.route methods mint and cache this token automatically; there is no public manual mint method. The HTTP request body is empty and the response is { data: GatewayContextToken }. Identity comes from the authenticated session and organization context."
}
OpenAPI metadata (incomplete):
{
"operationId": "createPortalConsumerGatewayToken",
"summary": "Create a short-lived gateway context token for the signed-in consumer",
"tags": [
"portal-customer"
],
"security": [
{
"consumerBearerAuth": []
},
{
"siteShellServiceJwt": [],
"personaSessionCookie": []
}
],
"parameters": [
{
"name": "businessId",
"in": "path",
"required": true,
"description": "Business identifier",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
},
"responses": {
"200": {
"description": "Signed gateway context token",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": false,
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"additionalProperties": false,
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"details": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": false,
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"additionalProperties": false,
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"details": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": false,
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"additionalProperties": false,
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"details": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
}
}
},
"404": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": false,
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"additionalProperties": false,
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"details": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
}
}
},
"409": {
"description": "Conflict",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": false,
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"additionalProperties": false,
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"details": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
}
}
}
}
}
{
"browserBearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT",
"description": "Browser session token forwarded by the frontend"
},
"consumerBearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT",
"description": "Consumer portal session token forwarded by the frontend"
},
"cliUserSessionBearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "cli_access JWT",
"description": "Short-lived CLI access JWT exchanged from a live user-bound fscli_ session. Eligibility is revalidated from current organization membership and role grants."
},
"makerTokenAccessBearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "cli_access JWT",
"description": "Short-lived CLI access JWT exchanged from an organization-scoped mk_ MakerToken. Authority is limited to the token's frozen exact grants and business scope."
},
"rawCliCredentialBearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "fscli_ session or mk_ MakerToken",
"description": "Raw CLI credential accepted only by exchange, organization discovery, and CLI-session revocation infrastructure."
},
"serviceJwtBearer": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "Ed25519 service JWT",
"description": "Short-lived Farther Shore service identity JWT for internal machine calls"
},
"siteShellServiceJwt": {
"type": "apiKey",
"in": "header",
"name": "x-fs-service-jwt",
"description": "Short-lived Farther Shore site-shell service JWT with proxy:trust scope"
},
"localPreviewProxyLease": {
"type": "apiKey",
"in": "header",
"name": "x-fs-local-persona-proxy",
"description": "CLI-process-only local-preview lease (fslpl_…) attached by the `farthershore frontend dev|preview --live` loopback proxy together with `x-fs-local-preview-origin` (the exact http://localhost:<port> origin it was issued for). Verified against Core's lease store and pinned to one persona/environment/business/portal host; a raw header pair without a live lease grants nothing. Never sent by browser code."
},
"personaSessionCookie": {
"type": "apiKey",
"in": "cookie",
"name": "__Host-fs_persona_session",
"description": "Host-only HttpOnly persona session cookie. Accepted only through a trusted boundary: together with the hosted site shell's service JWT, or through the CLI's localhost preview proxy presenting a verified local-preview lease (x-fs-local-persona-proxy + x-fs-local-preview-origin). Never as a bearer."
}
}