Pinned Execution

Use Pinned Execution when you need the same provider, model, API, and request settings every time. Hydracept sends the request as specified and returns an immutable execution record you can review or verify later.

Permanent path (no research alias):


POST /v1/inference/pinned
GET  /v1/inference/pinned/{receipt_id}
POST /v1/inference/pinned/bulk
GET  /v1/inference/pinned/bulk/{bulk_id}

POST /v1/inference/pinned/bulk accepts a shared pin plus an items array. Each item is an independent pinned execution with its own receipt — concurrent ordinary pins, not a provider-native Batch API. Pins stay on standard processing unless the caller sets processing: "deferred" on an eligible OpenAI Responses pin (service_tier=flex, 50% of standard token rates) — same pin, one logical model execution, no truncation rewrite, no Flex→Standard fallback. Pre-inference capacity 429s and connection refusals may retry inside the admission deadline and are recorded on the receipt. Tenant identity is the customer project, same as POST /v1/inference/pinned: a project-bound API key is enough; an unbound key must send context.projectId. Organization is derived from that project. A client-supplied organizationId is not authorization. The bulk is durable: submit returns accepted with nextAction: poll. Poll GET /v1/inference/pinned/bulk/{bulk_id} until nextAction is stop (succeeded, partial, or failed). In-flight items survive a service restart. Sibling items do not share a provider attempt; a failure on one item does not retry or cancel the others. Concurrency is a sliding window: a hung in-flight item does not block later items from starting. When capacity rejections spike, later submissions reduce concurrency instead of hammering the same ceiling.

Hydracept distinguishes three clocks:

  1. Execution timeout — limits.timeoutSeconds (or top-level timeoutSeconds) is the wall-clock budget for one admitted provider HTTP attempt. Default and platform maximum 600s. Trickling/thinking tokens do not extend this deadline. processing: "deferred" with an omitted timeout uses that same 600s max. Callers may set a lower value; a value above the platform maximum is rejected with 422. Minimum is 30s. Connect/write/pool timeouts remain underneath as transport protections.
  2. Admission/retry deadline — limits.admissionDeadlineSeconds is how long Hydracept may keep trying to get the request accepted after Flex-capacity 429s or connection refusal. Default 120s on standard pins and 900s on deferred pins. 0 means one HTTP submission. Maximum 1800s. Ambiguous failures after send (execution deadline, cancelled in-flight POST) are never retried. A durable dispatch boundary is persisted before each paid POST; unknown submission state is sealed as TRANSPORT_AMBIGUOUS rather than retried.
  3. Queue wait — time waiting to start (default bulk start window 20 minutes) plus time spent behind earlier in-flight items at the current concurrency. Recorded as schedulerWaitMs when known. This does not consume the execution timeout.

Connect/write/pool stay short so a failure before send is providerSubmission: not_attempted. A timeout or network error after send is providerSubmission: ambiguous and is never advertised as safely retryable. Receipts record logicalAttempts=1 plus providerSubmissions, capacityRejections, retryWaitMs, providerExecutionMs, and wallClockMs. safelyRetryable: false means do not POST the sealed pin again. This per-item provider timeout is distinct from bulkWait.timeoutSeconds (client poll of the whole bulk, default 3600s).

Semantics

Receipts

After completion, the execution record is immutable: selected settings, request hashes, attempts, usage, provider request ID, timestamps, and providerSubmission (not_attempted, ambiguous, or attempted) cannot change. Corrections are recorded separately.

GET /v1/inference/pinned/{receipt_id} returns that evidence after completion. Project-bound API keys can read receipts for their project; an organization on the principal is not required. Related receipts can be hashed into a run manifest; a stable pin becomes an AI lockfile. See Execution provenance.

Example


curl -sS -X POST \
  -H "Authorization: Bearer $HYDRACEPT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "pin": { "provider": "openai", "model": "gpt-5.6-sol", "api": "responses" },
    "isolation": "stateless",
    "instructions": "Return exactly what was asked.",
    "input": "ping"
  }' \
  https://api.hydracept.com/v1/inference/pinned

DeepSeek Flash, non-thinking, provider-enforced JSON:


curl -sS -X POST \
  -H "Authorization: Bearer $HYDRACEPT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "pin": { "provider": "deepseek", "model": "deepseek-flash", "api": "chat-completions" },
    "isolation": "stateless",
    "sampling": { "thinking": "disabled" },
    "responseFormat": { "type": "json_object" },
    "instructions": "Return JSON only.",
    "input": "extract the id"
  }' \
  https://api.hydracept.com/v1/inference/pinned

Responses json_schema:


{
  "pin": { "provider": "deepseek", "model": "deepseek-flash", "api": "responses" },
  "sampling": { "thinking": "disabled" },
  "responseFormat": {
    "type": "json_schema",
    "name": "extract",
    "schema": { "type": "object", "properties": { "id": { "type": "string" } } }
  },
  "instructions": "Return JSON only.",
  "input": "extract the id"
}

Python SDK:


from hydracept import HydraceptClient
client = HydraceptClient(os.environ["HYDRACEPT_API_URL"], os.environ["HYDRACEPT_API_KEY"])
result = client.create_pinned_inference({
    "pin": {"provider": "openai", "model": "gpt-5.6-sol", "api": "responses"},
    "isolation": "stateless",
    "input": "ping",
})
receipt = client.get_pinned_receipt(result["receipt"]["receipt_id"])

bulk = client.create_pinned_inference_bulk({
    "pin": {"provider": "openai", "model": "gpt-5.6-sol", "api": "responses"},
    "isolation": "stateless",
    "concurrency": 8,
    "items": [
        {"id": "cell-1", "input": "ping"},
        {"id": "cell-2", "input": "pong"},
    ],
})
done = client.wait_pinned_bulk(bulk["bulkId"])

TypeScript:


await client.runtime.createPinnedInference({
  pin: { provider: "openai", model: "gpt-5.6-sol", api: "responses" },
  isolation: "stateless",
  input: "ping",
});

.NET:


await client.CreatePinnedInferenceAsync(body);

CLI: python -m hydracept pinned run body.json, python -m hydracept pinned bulk body.json --wait, python -m hydracept pinned get <receipt_id>, then python -m hydracept lockfile emit <receipt_id> and python -m hydracept verify.

Verification

Pinned receipts are immutable after completion, so you can verify a run after the fact:


python -m hydracept pinned get <receipt_id>
python -m hydracept verify

Related receipts can be grouped into a run manifest, and a stable pin can be emitted as an AI lockfile. See Execution provenance.