SolidHooksSolidHooks/ Docs

Throughput and rate limits

The three separate limits in SolidHooks, what each one returns, and which are errors and which only slow things down.

"Rate limit" covers three different mechanisms here, and they behave differently. One limits calls to the management API, one limits inbound webhooks, and one paces outbound deliveries. Only the first two ever return an error.

API requests

An API key (sdhk_sk_...) is limited to 600 requests per minute per key. Beyond that the API returns 429. Back off and retry.

The dashboard's /auth/* account endpoints carry their own per-IP limits, which you will not meet when calling /v1 with a key.

Inbound webhooks

Two things can reject an inbound request at the ingest origin (https://sdhk.events/<maskId>), both before anything is stored.

Ingest throughput

LimitScopeNotes
Source rateLimitOne sourceRequests per second. 0 means unlimited and is the default, so most sources never see it. Read-only on the API: support sets it.
Organisation clampWhole organisationCan be applied to a whole organisation. Checked after the source's limit.

When either trips, ingest responds 429 with code RATE_LIMITED, a body of data: { limit, remaining, retryAfterSeconds }, and the headers Retry-After, X-RateLimit-Limit and X-RateLimit-Remaining. The sender still holds the payload, so this is an error on purpose: back off for Retry-After seconds and resend.

Monthly delivery quota

Your plan includes a number of deliveries per usage window. The billable unit is the delivery (one event routed to one connection), so fan-out to three connections counts three. Retries are free, replays are billed, and duplicate (idempotent) requests are never counted.

What happens at the limit depends on the plan:

  • Hard-capped plans (the free Hobby tier) reject ingest with 429 QUOTA_EXCEEDED and data: { limit, current, resetAt } until the window resets or you upgrade. Event replay is gated the same way.
  • Paid plans with overage enabled never hard-cap. Deliveries beyond the included quota are metered and billed as pay-as-you-go.

The window is the subscription's billing period for subscribed organisations and the UTC calendar month otherwise. GET /v1/billing/usage shows usage against the quota and resetAt.

Outbound delivery pacing

Delivery pacing limits how fast SolidHooks sends to your endpoint. It is never an error. A delivery over the rate is queued and sent when capacity frees up. Nothing is dropped, no retry attempt is consumed, and you do not need to act.

Two limits apply, layered:

  • Plan pacing: maxDeliveriesPerSecond and burstDeliveriesPerSecond in the plan's entitlements, across your whole organisation. null means unlimited.
  • Destination pacing: rateLimit and rateLimitPeriod on a destination, which you set to protect that endpoint. rateLimitPeriod is second, minute, hour or day.
PlanmaxDeliveriesPerSecondburstDeliveriesPerSecond
Hobby1020
Launch50100
Scale200400
Enterpriseunlimitedunlimited
curl -s -X PATCH "$API/v1/destinations/dest_..." \
  -H "authorization: Bearer $SDHK_KEY" \
  -H 'content-type: application/json' \
  -d '{ "data": { "rateLimit": 100, "rateLimitPeriod": "minute" } }'

A held delivery has status: "throttled" and throttledReason: "rate_limit". This is different from destination_busy, which is a delivery parked because your endpoint answered 429, 502 or 504 (see Retries). A delivery that was ever held keeps a throttledAt timestamp, even after it succeeds.

GET /v1/deliveries/stats returns the live queue as { pending, throttled }, the number of deliveries waiting right now. Historical outcome counts are in GET /v1/stats/dashboard.

Retrying a throttled delivery

POST /v1/deliveries/{id}/retry returns 409 CONFLICT for a throttled delivery. It is already queued and will send on its own.

Connector endpoints

The public connector endpoints (/v1/connectors/bootstrap and /v1/connectors/replicas/heartbeat) allow 5 requests per second per client IP with a burst of 20, applied before the token is checked. After the token resolves, bootstrap is limited to about one per 5 seconds per connector and heartbeats to one per second per replica. See Private delivery.

Next steps

  • Retries — the retry schedule and how responses are interpreted
  • Plans — entitlements and quota per plan
  • Errors — error codes across the API
  • Destinations — set rateLimit on a destination