openapi: 3.2.0 info: title: Ablo Credentials API version: 0.55.0 description: 'Ablo collaboration infrastructure: commit, read, and claim. `{model}` is any model from your pushed schema — the routes are the same whichever it is. Authenticate every request with your API key as a Bearer token.' license: name: Apache License 2.0 identifier: Apache-2.0 servers: - url: https://api.abloatai.com/api description: Production - url: http://localhost:8787/api description: Local development security: - bearerAuth: [] tags: - name: credentials paths: /v1/ephemeral_keys: post: tags: - credentials summary: Mint a short-lived session credential description: 'Call this first: every other route needs the key it returns. Requires a secret (`sk_`) key — a session cannot mint itself.' requestBody: required: true content: application/json: schema: type: object properties: user: type: object properties: id: type: string minLength: 1 teamIds: type: array items: type: string required: - id organizationId: type: string minLength: 1 schemaProjectId: type: string minLength: 1 schemaOwnerOrgId: type: string minLength: 1 syncGroups: readOnly: true type: array items: anyOf: - type: string const: default - type: string pattern: ^[a-z][a-z0-9_]*:[\s\S]{1,}$ operations: minItems: 1 type: array items: type: string pattern: ^[^.\s]+\.(read|create|update|delete)$ activeSchemaOperations: minItems: 1 type: array items: type: string enum: - read - create - update - delete controlPlaneOnly: type: boolean const: true ttlSeconds: type: integer exclusiveMinimum: 0 maximum: 9007199254740991 label: type: string minLength: 1 required: - user responses: '201': description: The minted credential content: application/json: schema: type: object properties: object: type: string const: ephemeral_key id: type: string minLength: 1 expiresAt: type: string minLength: 1 organizationId: type: string minLength: 1 participantId: type: string minLength: 1 projectId: default: null anyOf: - type: string minLength: 1 - type: 'null' branchId: default: null anyOf: - type: string minLength: 1 - type: 'null' branchRoot: default: false type: boolean syncGroups: type: array items: type: string deliveryPartition: default: null anyOf: - type: object properties: index: type: integer minimum: 0 maximum: 9007199254740991 count: type: integer minimum: 2 maximum: 9007199254740991 required: - index - count additionalProperties: false - type: 'null' operations: type: array items: type: string pattern: ^[^.\s]+\.(read|create|update|delete)$ controlPlaneOnly: type: boolean const: true token: type: string minLength: 1 required: - id - expiresAt - organizationId - participantId - projectId - branchId - branchRoot - syncGroups - deliveryPartition - operations - token additionalProperties: false '400': description: The request did not satisfy the published contract. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '401': description: The Bearer credential is missing, malformed, or expired. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '403': description: The credential does not authorize this operation. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '404': description: The addressed resource does not exist in the credential scope. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '409': description: The request conflicts with current claim, version, or idempotency state. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '429': description: The caller exceeded an enforced rate limit. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '500': description: The server could not complete the request. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '503': description: A required service is temporarily unavailable. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' default: description: An HTTP error not otherwise listed; decoded through the canonical envelope. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' operationId: mintEphemeralKey /v1/branches/{id}/credentials: post: tags: - credentials summary: Mint an expiring branch-bound test credential parameters: - name: id in: path required: true schema: type: string requestBody: required: false content: application/json: schema: type: object properties: ttl_hours: type: integer minimum: 1 maximum: 168 additionalProperties: false responses: '201': description: A one-time plaintext credential. Do not persist it in source control. content: application/json: schema: type: object properties: object: type: string const: branch_credential branch_id: type: string api_key: type: string expires_at: type: string required: - object - branch_id - api_key - expires_at additionalProperties: false '400': description: The request did not satisfy the published contract. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '401': description: The Bearer credential is missing, malformed, or expired. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '403': description: The credential does not authorize this operation. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '404': description: The addressed resource does not exist in the credential scope. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '409': description: The request conflicts with current claim, version, or idempotency state. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '429': description: The caller exceeded an enforced rate limit. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '500': description: The server could not complete the request. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '503': description: A required service is temporarily unavailable. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' default: description: An HTTP error not otherwise listed; decoded through the canonical envelope. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' operationId: mintBranchCredential /v1/capabilities: post: tags: - credentials summary: Mint a capability for an agent or system description: 'A scoped, revocable grant. Narrow by default: an agent or system capability must name its `syncGroups` and `operations`.' requestBody: required: true content: application/json: schema: type: object properties: participantKind: type: string enum: - user - agent - system participantId: type: string minLength: 1 organizationId: type: string minLength: 1 syncGroups: readOnly: true type: array items: anyOf: - type: string const: default - type: string pattern: ^[a-z][a-z0-9_]*:[\s\S]{1,}$ operations: readOnly: true type: array items: type: string pattern: ^[^.\s]+\.(read|create|update|delete)$ ttlSeconds: type: integer exclusiveMinimum: 0 maximum: 9007199254740991 label: type: string minLength: 1 wideScope: type: boolean userMeta: type: object additionalProperties: true required: - participantKind - ttlSeconds responses: '201': description: The minted capability. `token` is the credential — carry it as the Bearer token on every other call. `scope` is what was minted, which is not always what was asked for. content: application/json: schema: type: object properties: capabilityId: type: string minLength: 1 token: type: string minLength: 1 expiresAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ organizationId: type: string minLength: 1 branchRoot: default: false type: boolean scope: type: object properties: organizationId: type: string minLength: 1 projectId: default: null anyOf: - type: string minLength: 1 - type: 'null' branchId: default: null anyOf: - type: string minLength: 1 - type: 'null' syncGroups: type: array items: type: string operations: type: array items: type: string pattern: ^[^.\s]+\.(read|create|update|delete)$ participantKind: type: string enum: - user - agent - system participantId: type: string minLength: 1 deliveryPartition: default: null anyOf: - type: object properties: index: type: integer minimum: 0 maximum: 9007199254740991 count: type: integer minimum: 2 maximum: 9007199254740991 required: - index - count additionalProperties: false - type: 'null' required: - organizationId - projectId - branchId - syncGroups - operations - participantKind - participantId - deliveryPartition additionalProperties: false userMeta: type: object additionalProperties: true required: - capabilityId - token - expiresAt - organizationId - branchRoot - scope - userMeta additionalProperties: false '400': description: The request did not satisfy the published contract. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '401': description: The Bearer credential is missing, malformed, or expired. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '403': description: The credential does not authorize this operation. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '404': description: The addressed resource does not exist in the credential scope. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '409': description: The request conflicts with current claim, version, or idempotency state. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '429': description: The caller exceeded an enforced rate limit. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '500': description: The server could not complete the request. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '503': description: A required service is temporarily unavailable. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' default: description: An HTTP error not otherwise listed; decoded through the canonical envelope. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' operationId: mintCapability /v1/capabilities/{id}: get: tags: - credentials summary: Inspect a capability parameters: - name: id in: path required: true schema: type: string responses: '200': description: The capability content: application/json: schema: type: object '400': description: The request did not satisfy the published contract. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '401': description: The Bearer credential is missing, malformed, or expired. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '403': description: The credential does not authorize this operation. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '404': description: The addressed resource does not exist in the credential scope. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '409': description: The request conflicts with current claim, version, or idempotency state. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '429': description: The caller exceeded an enforced rate limit. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '500': description: The server could not complete the request. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '503': description: A required service is temporarily unavailable. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' default: description: An HTTP error not otherwise listed; decoded through the canonical envelope. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' operationId: getCapability delete: tags: - credentials summary: Revoke a capability parameters: - name: id in: path required: true schema: type: string responses: '200': description: Revoked content: application/json: schema: type: object properties: id: type: string minLength: 1 deleted: type: boolean const: true activeSessionsClosed: type: integer minimum: 0 maximum: 9007199254740991 required: - id - deleted - activeSessionsClosed additionalProperties: false '400': description: The request did not satisfy the published contract. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '401': description: The Bearer credential is missing, malformed, or expired. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '403': description: The credential does not authorize this operation. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '404': description: The addressed resource does not exist in the credential scope. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '409': description: The request conflicts with current claim, version, or idempotency state. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '429': description: The caller exceeded an enforced rate limit. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '500': description: The server could not complete the request. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '503': description: A required service is temporarily unavailable. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' default: description: An HTTP error not otherwise listed; decoded through the canonical envelope. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' operationId: revokeCapability /v1/capabilities/{id}/rotate: post: tags: - credentials summary: Rotate a capability, keeping its grant parameters: - name: id in: path required: true schema: type: string requestBody: required: false content: application/json: schema: type: object properties: graceSeconds: type: integer exclusiveMinimum: 0 maximum: 9007199254740991 ttlSeconds: type: integer exclusiveMinimum: 0 maximum: 9007199254740991 responses: '201': description: The rotated capability content: application/json: schema: type: object properties: capabilityId: type: string minLength: 1 token: type: string minLength: 1 expiresAt: anyOf: - type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ - type: 'null' organizationId: type: string minLength: 1 branchRoot: default: false type: boolean scope: type: object properties: organizationId: type: string minLength: 1 projectId: default: null anyOf: - type: string minLength: 1 - type: 'null' branchId: default: null anyOf: - type: string minLength: 1 - type: 'null' syncGroups: type: array items: type: string operations: type: array items: type: string pattern: ^[^.\s]+\.(read|create|update|delete)$ participantKind: type: string enum: - user - agent - system participantId: type: string minLength: 1 deliveryPartition: default: null anyOf: - type: object properties: index: type: integer minimum: 0 maximum: 9007199254740991 count: type: integer minimum: 2 maximum: 9007199254740991 required: - index - count additionalProperties: false - type: 'null' required: - organizationId - projectId - branchId - syncGroups - operations - participantKind - participantId - deliveryPartition additionalProperties: false rotatedFrom: type: object properties: capabilityId: type: string minLength: 1 expiresAt: type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ required: - capabilityId - expiresAt additionalProperties: false required: - capabilityId - token - expiresAt - organizationId - branchRoot - scope - rotatedFrom additionalProperties: false '400': description: The request did not satisfy the published contract. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '401': description: The Bearer credential is missing, malformed, or expired. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '403': description: The credential does not authorize this operation. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '404': description: The addressed resource does not exist in the credential scope. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '409': description: The request conflicts with current claim, version, or idempotency state. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '429': description: The caller exceeded an enforced rate limit. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '500': description: The server could not complete the request. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '503': description: A required service is temporarily unavailable. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' default: description: An HTTP error not otherwise listed; decoded through the canonical envelope. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' operationId: rotateCapability components: schemas: ErrorEnvelope: type: object properties: type: type: string code: type: string param: type: string message: type: string doc_url: type: string request_id: type: string event_id: type: string errors: readOnly: true type: array items: readOnly: true type: object properties: code: type: string message: type: string param: type: string required: - message additionalProperties: false required: - type - message additionalProperties: true securitySchemes: bearerAuth: type: http scheme: bearer description: Your Ablo API key (sk_… / rk_…).