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, orAuthorization: Bearer/Swarmviawhen 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
- Acquire a slot.
- Call the upstream from your process.
- Renew on the recommended interval while the call runs.
- 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
- Acquire a concurrency lock without proxying (cookbook)
- Sources (when swarmvia should call the upstream for you)
- Admission errors