Talentino Docs
API ReferencePipeline API (internal)

Lock credits for an action

POST/credits/lock

Synchronously reserves the credits for one billable action before the caller performs it. The handler runs a sufficiency check — (subscription remaining + on-demand remaining − already-locked reservations) ≥ action cost — and, when it passes, inserts a lock row reserving the cost. The action's cost is read from the action_types table (Redis-cached), so pricing changes need no API change.

Idempotency: the lock is keyed by the caller-supplied operation_id (your stable record id). Retrying the same operation_id does not create a second reservation and returns the same 200 — safe to retry on timeouts.

Allocation gate: while a credit (re)allocation for the Business Unit is in progress (Redis gate), the handler briefly re-polls (~4s total) and then returns 409 with retry: true — retry once the allocation settles.

A reservation stays held until it is settled via POST /credits/settle. There is no auto-expiry yet: a never-settled lock keeps its credits reserved.

Authorization

creditsApiKey
AuthorizationBearer <token>

Static bearer key for the Credit API, shared per-service (the CREDITS_API_KEY SST secret — the calling service is provisioned with the same value). The header must be exactly Authorization: Bearer <CREDITS_API_KEY>. This is an application-level check (no API Gateway authorizer) and it fails closed: if the secret is unset, every request is rejected with 401.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/credits/lock" \  -H "Content-Type: application/json" \  -d '{    "name": "request_info",    "business_unit_id": 42,    "operation_id": "request-info-789"  }'
{  "locked": true,  "operation_id": "request-info-789",  "amount": 1}
{  "error": "invalid_request",  "issues": [    {      "path": [        "business_unit_id"      ],      "message": "Invalid input: expected number, received string"    }  ]}
{  "message": "Unauthorized"}
{  "error": "insufficient_credits",  "required": 1,  "available": 0}
{  "error": "credits_allocation_in_progress",  "retry": true}
{  "message": "Internal server error"}