openapi: 3.2.0
info:
title: Ablo Claims 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: claims
paths:
/v1/models/{model}/{id}/claim:
post:
tags:
- claims
summary: Claim a row (acquire lease)
parameters:
- name: model
in: path
required: true
schema:
type: string
description: A model name from your pushed schema, e.g. `item`.
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
claimId:
type: string
target:
anyOf:
- type: object
properties:
model:
type: string
id:
anyOf:
- type: string
- type: 'null'
field:
type: string
fields:
readOnly: true
type: array
items:
type: string
meta:
type: object
additionalProperties: true
- type: 'null'
reason:
type: string
description:
type: string
meta:
type: object
additionalProperties: true
ttl:
anyOf:
- anyOf:
- type: number
exclusiveMinimum: 0
- type: string
pattern: ^(\d+(?:\.\d+)?)(ms|s|m|h)$
- type: 'null'
queue:
type: boolean
responses:
'201':
description: The lease is yours. `claim.fenceToken` is set when the coordinator minted one; carry it on writes made under the lease.
content:
application/json:
schema:
$ref: '#/components/schemas/ClaimAcquire'
'202':
description: The row was already held and you asked to queue. You are in line at `position` — heartbeat to keep the slot, and poll `GET /v1/claims/{claimId}` for the grant.
content:
application/json:
schema:
$ref: '#/components/schemas/ClaimAcquire'
'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: acquireModelClaim
delete:
tags:
- claims
summary: Release a claim
parameters:
- name: model
in: path
required: true
schema:
type: string
description: A model name from your pushed schema, e.g. `item`.
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Released
content:
application/json:
schema:
$ref: '#/components/schemas/ClaimRelease'
'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: releaseModelClaim
/v1/models/{model}/{id}/claim/heartbeat:
post:
tags:
- claims
summary: Heartbeat a held claim (extend the lease for long-running work)
parameters:
- name: model
in: path
required: true
schema:
type: string
description: A model name from your pushed schema, e.g. `item`.
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
claimId:
type: string
ttl:
anyOf:
- anyOf:
- type: number
exclusiveMinimum: 0
- type: string
pattern: ^(\d+(?:\.\d+)?)(ms|s|m|h)$
- type: 'null'
details:
type: object
additionalProperties: true
responses:
'200':
description: Lease extended (or queued slot refreshed)
content:
application/json:
schema:
$ref: '#/components/schemas/ClaimHeartbeat'
'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: heartbeatModelClaim
/v1/models/{model}/{id}/claim/reorder:
post:
tags:
- claims
summary: Reorder the wait-line (privileged)
description: Name the waiters you want at the front, in the order you want them. Waiters you leave out keep their relative places behind them.
parameters:
- name: model
in: path
required: true
schema:
type: string
description: A model name from your pushed schema, e.g. `item`.
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
order:
readOnly: true
type: array
items:
type: object
properties:
heldBy:
type: string
claimId:
type: string
required:
- heldBy
- claimId
responses:
'200':
description: Reordered
content:
application/json:
schema:
$ref: '#/components/schemas/ClaimReorder'
'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: reorderModelClaimQueue
/v1/claims:
get:
tags:
- claims
summary: List who holds what, and who waits
description: 'The coordination view: scope to a row with `model` and `id`, to a participant with `actorId`, `actorKind`, `onBehalfOfId` or `capabilityId`, or combine them. `queue` is populated only when the request names both `model` and `id` — a wait line belongs to one row.'
parameters:
- name: model
in: query
schema:
type: string
- name: id
in: query
schema:
type: string
- name: field
in: query
schema:
type: string
- name: actorId
in: query
schema:
type: string
- name: actorKind
in: query
schema:
type: string
enum:
- user
- agent
- system
- name: onBehalfOfId
in: query
schema:
type: string
- name: capabilityId
in: query
schema:
type: string
responses:
'200':
description: Live claims, and the wait line behind the named row.
content:
application/json:
schema:
$ref: '#/components/schemas/ClaimList'
'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: listClaims
post:
tags:
- claims
summary: Claim a row named in the body
description: The same operation as `POST /v1/models/{model}/{id}/claim`, with the row in `target` instead of the URL. Answers identically.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
claimId:
type: string
target:
anyOf:
- type: object
properties:
model:
type: string
id:
anyOf:
- type: string
- type: 'null'
field:
type: string
fields:
readOnly: true
type: array
items:
type: string
meta:
type: object
additionalProperties: true
- type: 'null'
reason:
type: string
description:
type: string
meta:
type: object
additionalProperties: true
ttl:
anyOf:
- anyOf:
- type: number
exclusiveMinimum: 0
- type: string
pattern: ^(\d+(?:\.\d+)?)(ms|s|m|h)$
- type: 'null'
queue:
type: boolean
responses:
'201':
description: The lease is yours.
content:
application/json:
schema:
$ref: '#/components/schemas/ClaimAcquire'
'202':
description: Already held, and you asked to queue. You are in line at `position`.
content:
application/json:
schema:
$ref: '#/components/schemas/ClaimAcquire'
'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: acquireClaim
/v1/claims/heartbeat:
post:
tags:
- claims
summary: Heartbeat every lease you hold, in one request
description: One round trip per cadence for a worker holding many rows, instead of one per row. Takes only `ttl`; the leases are whichever ones your credential holds on this branch.
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
claimId:
type: string
ttl:
anyOf:
- anyOf:
- type: number
exclusiveMinimum: 0
- type: string
pattern: ^(\d+(?:\.\d+)?)(ms|s|m|h)$
- type: 'null'
details:
type: object
additionalProperties: true
responses:
'200':
description: One ack per lease extended.
content:
application/json:
schema:
$ref: '#/components/schemas/ClaimHeartbeatBatch'
'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: heartbeatClaims
/v1/claims/{claimId}:
get:
tags:
- claims
summary: Poll a claim for its current state
description: How a caller without a persistent connection learns its queued claim was granted. `position` is advisory — a privileged reorder can move it up — so branch on `status`, never on position.
parameters:
- name: claimId
in: path
required: true
schema:
type: string
responses:
'200':
description: The claim state
content:
application/json:
schema:
$ref: '#/components/schemas/ClaimState'
'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: getClaim
delete:
tags:
- claims
summary: Release a claim, or leave the wait line
description: 'The same call for both: releasing a held lease and abandoning a queued position are one operation, because a queue entry is a lease in a different state.'
parameters:
- name: claimId
in: path
required: true
schema:
type: string
responses:
'200':
description: Released
content:
application/json:
schema:
$ref: '#/components/schemas/ClaimRelease'
'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: releaseClaim
/v1/claims/{claimId}/heartbeat:
post:
tags:
- claims
summary: Heartbeat a claim by id — held or queued
description: 'Keep a held or queued claim active. Branch on the returned status: `queued` is still waiting and `held` has been granted. Retrieve the claim after a grant before writing.'
parameters:
- name: claimId
in: path
required: true
schema:
type: string
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
claimId:
type: string
ttl:
anyOf:
- anyOf:
- type: number
exclusiveMinimum: 0
- type: string
pattern: ^(\d+(?:\.\d+)?)(ms|s|m|h)$
- type: 'null'
details:
type: object
additionalProperties: true
responses:
'200':
description: Lease extended, or queued slot refreshed.
content:
application/json:
schema:
$ref: '#/components/schemas/ClaimHeartbeat'
'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
# --- truncated at 32 KB (41 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/abloatai/refs/heads/main/openapi/abloatai-claims-api-openapi.yml