Concurrency locks

Base URL

Lock routes live only on https://api.swarmvia.cloud/pools/{source}/lock, never on ‹source›.swarmvia.cloud. {source} is your source subdomain (for example prod-acme). The path keeps its /pools/ segment. The Examples section on the source Overview page in the dashboard includes acquire, renew, and release.

All lock endpoints are POST and return JSON.

Authentication

Same caller auth as the source:

  • Access key (X-Swarmvia-Key, or Authorization: Bearer / Swarmvia when allowed)
  • Optional JWT, Cloudflare Access, and IP policies from Access

Access keys expire, and renew and release check the key too. Hold a key that outlives the slot; a worker that runs for days mints fresh keys as described in Refresh access tokens before they expire.

The lock API never emits managed upstream credentials. You authenticate to the source for a slot, then call the upstream yourself with whatever auth the origin expects.

First request

export ACCESS_KEY='sv_at_…'
export LOCK_API='https://api.swarmvia.cloud/pools/your-source/lock'

curl -sS -X POST "$LOCK_API/acquire" \
  -H "X-Swarmvia-Key: $ACCESS_KEY" \
  -H "Content-Type: application/json"

A 200 body looks like:

{
  "slotId": "…",
  "leaseDeadline": 1710000030000,
  "requestDeadline": 1710000060000,
  "termMs": 30000,
  "renewIntervalMs": 10000
}

Hold slotId privately. Renew before leaseDeadline (about every renewIntervalMs, typically 10s). Renewal never extends past requestDeadline (the source's request/lease timeout). A vanished client's slot is reclaimed within one term (termMs, typically 30s).

Endpoints

POST /pools/{source}/lock/acquire

Body (optional JSON):

Field Meaning
waitMs Opt-in queue wait in milliseconds (clamped to the source's queue timeout). Absent → fail fast

You can also set wait with X-Swarmvia-Queue-Timeout-Ms. The JSON body wins if both are present. X-Swarmvia-No-Queue forces fail-fast even when waitMs is set.

Success 200: Lock grant fields above, plus the usual governor response headers (x-swarmvia-remaining-slots, x-swarmvia-effective-limit, x-swarmvia-queued-ms, …).

Errors:

Status error When
401 unauthorized Missing, invalid, expired, or revoked credentials
403 unauthorized IP allowlist miss
413 payload_too_large Body too large
429 too_many_requests No free slot (fail-fast or queue full). May include Retry-After
504 queue_timeout Waited waitMs (or header budget) and no slot opened

Acquire attempts are written to the source access log. Renew and release are not.

POST /pools/{source}/lock/{slotId}/renew

Empty body. Call on a timer while your upstream work runs (every renewIntervalMs).

Status Body When
200 { "leaseDeadline": … } Term extended
404 not_found Slot already released or reclaimed
409 capped Slot hit the request-timeout cap. Release it.

POST /pools/{source}/lock/{slotId}/release

Body (optional JSON). Outcome report that feeds adaptive concurrency / RPM learning (same rate-header dialects as the proxy):

Field Meaning
status Final upstream HTTP status (100-599)
throttled Count of upstream 429s you observed
retryAfterMs Upstream retry hint in milliseconds
rate Pre-parsed rate fields (limit, remaining, resetMs, tokenLimit, …)
headers Raw upstream response headers to parse (x-ratelimit-*, etc.)

If both rate and headers are sent, rate wins.

Success 200: { "released": true } when the slot was held, or { "released": false } if it was already gone (idempotent).

curl -sS -X POST "$LOCK_API/$SLOT_ID/release" \
  -H "X-Swarmvia-Key: $ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":200}'

Throttle report example:

curl -sS -X POST "$LOCK_API/$SLOT_ID/release" \
  -H "X-Swarmvia-Key: $ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":429,"throttled":1,"retryAfterMs":2000}'

Lifecycle

  1. Acquire a slot.
  2. Call the upstream from your process.
  3. Renew on the recommended interval while the call runs.
  4. Release when finished (include outcome fields when you saw throttling).

Acquire shares the source's concurrency limit, queue, and RPM gate with proxy traffic. See Concurrency for those settings.

See also