Skip to main content
developers/donations-sdk/operations
Developer9 min read

Operations

Versioning policy, deprecation timeline, rate limits, and key management policy for the Donations Embed.

Operations

Operational policies for the Donations Embed: how we version, how long deprecation windows last, what the rate limits are, and how key management works.

Versioning policy

The Donations Embed follows Semantic Versioning. Three things are versioned independently:

  • The API — the HTTP endpoints exposed at https://api.1stflock.com. The current major is v1; every endpoint is prefixed /v1/embed/. A future major version (v2) will live under /v2/embed/ and will not silently break existing integrations.
  • The browser embed bundle — the JavaScript shipped at https://payments.1stflock.com/v1.js (live mode, paired with pk_live_… keys) and at https://sandbox.payments.1stflock.com/v1.js (sandbox mode, paired with pk_test_… keys). The current major is v1. A future v2 will ship at /v2.js on both hosts. Existing <script src="…/v1.js"> tags will continue to work after a v2 is released.
  • The server SDKs — @1st-flock/donations-embed-node, onefirstflock-donations-embed, and the Go module. Each follows semver in its own package registry. The current major is 1.x.x in every language. A future 2.x will ship under the same package name with a major-version bump.

What "v1" guarantees

Within v1 of any of the three artifacts:

  • Additive changes — new fields on response bodies, new optional request parameters, new event types, new attributes on the embed, new methods on the SDKs — happen freely. Your code keeps working unless it explicitly forbids unknown fields (which you should not do).
  • Behavioural improvements — better error messages, lower latency, broader retry coverage — happen freely.
  • Breaking changes — removing a field, changing a field's type, removing a method, changing the meaning of an existing attribute — DO NOT happen. They wait for a major-version bump.

Patch and minor releases

  • Patch (1.0.x) — bug fixes only. No new public surface.
  • Minor (1.x.0) — additive changes. Backwards-compatible new features.
  • Major (2.0.0) — breaking changes. Ships under a new URL path so existing integrations are never silently affected. Accompanied by a 12-month deprecation window for the previous major.

Deprecation timeline

When we deprecate a feature, the timeline is:

DayEvent
0Deprecation announced via the Changelog, in-Hub notification (when your account uses the deprecated surface), and an email to your account contacts.
0–365Deprecated feature continues to work exactly as before. New deployments using the deprecated surface receive a Hub-side warning banner.
365Deprecated feature is removed. Calls to it return a clear error pointing to the replacement.

We do not remove anything inside a deprecation window. The 365-day clock is enforced for breaking changes within v1 (rare, but we reserve the option for security-driven removals) and for the v1 → v2 transition.

For security-critical removals (CVE response), we reserve the right to compress the window. We commit to communicating any compression at least 30 days before the new removal date, and we will not compress for non-security reasons.

How you will hear about deprecations

  1. Changelog — every deprecation lands in the Changelog at the time of announcement.
  2. In-Hub banner — if your organisation is using the deprecated surface, the Hub displays a banner on the Donations Embed dashboard with a link to migration instructions.
  3. Email — your account's listed contacts receive a deprecation email at announcement, at the 90-day mark, at the 30-day mark, and at the 7-day mark.
  4. API response header — calls to a deprecated endpoint include Flock-Deprecation: <removal-date-iso> so your own monitoring can flag it.

The Hub banner and the API response header are the most important — they tell you specifically which surface in your specific integration is the problem.

Rate limits

CohortLimitBucket
Browser embed (publishable key)60 requests / minuteper (publishable key, source IP)
Customer SDK (secret key)1000 requests / minuteper (secret key, source IP)
Hub portal1000 requests / minuteper (user, source IP)

Rate limits use a sliding window with a 1-second granularity. Bursts are absorbed up to the per-minute total; sustained traffic above the limit returns 429.

Rate-limit response

When the limit is exceeded, the API returns 429 with:

HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json

{
  "code": "rate_limited",
  "message": "rate limit exceeded"
}

The Retry-After header gives the seconds to wait before retrying. Each SDK surfaces this as a RateLimitError with retryAfter / retry_after parsed from the header.

The 60-req/min browser limit is generous for a per-donor-IP limit (a single donor will not generate 60 requests in a normal flow). The 1000-req/min secret-key limit accommodates per-second polling and bulk operations comfortably.

If you need a higher limit, contact your account manager. We do not raise limits to defeat abuse protections, but we will accommodate genuine workload growth.

Key management

Key types

TypePrefixWhere it goesExpires
Publishablepk_live_… / pk_test_…Browser embed, client-side code, public HTMLNever (until revoked or rotated)
Secretsk_live_… / sk_test_…Server environment variables onlyNever (until revoked or rotated)
Webhook signingwhsec_…Server environment variables onlyNever (until rotated)

A "key pair" is one publishable + one secret key, created together and tied to the same environment (live or test).

Creation

Generate keys in the Hub under Donations Embed → Keys. Click Create key pair, set the environment, and give it a descriptive name.

The Hub returns the secret key exactly once at creation time. Store it immediately in your secrets manager. Subsequent reads of the key pair show the publishable key in full but only show a truncated prefix of the secret (e.g. sk_live_a1b2c3d4…). The only way to recover access if you lose the secret is to rotate the pair.

Rotation

To rotate a key pair, click Rotate on the key pair in the Hub. We:

  1. Issue a new (publishable, secret) pair with the same name and environment.
  2. Return the new secret once in the response.
  3. Keep the previous pair valid for 24 hours as a grace window so you can deploy the new keys without downtime.

After 24 hours, the old pair stops working and any traffic still using it returns 401.

The 24-hour grace window is the recommended way to do a zero-downtime rotation:

  1. Rotate in the Hub. Save the new secret.
  2. Update your deployments to use the new pair.
  3. Verify the new pair is in use (check the Hub's Last used at column or your own logs).
  4. Optional: revoke the old pair explicitly to close the window early once you have confirmed the new pair is taking all traffic.

Revocation

Click Revoke on a key pair in the Hub. Revocation is immediate — there is no grace window. Subsequent requests authenticated with either half of the pair return 401.

Use revocation when:

  • A key has been confirmed compromised (immediately stop the bad actor's access).
  • A key is no longer needed (clean up after a project ends).

For routine credential rotation, prefer rotate (which gives you the 24-hour overlap) over revoke + create (which gives you immediate downtime).

Origin allowlist

Publishable keys are scoped to one or more origin patterns. Set the allowlist under Donations Embed → Keys → Edit allowlist for the key. Each entry must match ^(\*\.)?[A-Za-z0-9.-]+(:\*|:\d+)?$:

PatternMatches
donations.example.orgExactly that origin.
*.example.orgAny subdomain of example.org (including donations.example.org and give.example.org, but NOT example.org itself).
localhost:3000Local development on port 3000.
localhost:*Local development on any port.

Browsers send the Origin header on every cross-origin request; if the origin does not match any pattern on the key's allowlist, the API returns 403. This means a leaked publishable key cannot be used from a domain you do not control.

Automatic freezing

We monitor publishable keys for card-testing patterns — bursts of declined attempts within a short window. When detected, the key pair is frozen automatically:

  1. Subsequent requests authenticated with either half of the pair return 403.
  2. A key.frozen webhook event is delivered to your endpoint with the trigger details (number of declines, window, frozen-at timestamp).
  3. The Hub displays a banner on the dashboard.

To recover:

  1. Investigate the source of the abusive traffic. Often it is your publishable key being used from a domain you do not own — adjust the origin allowlist to lock it down.
  2. Rotate the pair from the Hub.
  3. Update your deployments to use the new pair.
  4. Contact 1st Flock support if you need the original pair manually unfrozen (rare; typically rotation is sufficient).

The freeze threshold is conservative — it triggers on patterns that are extremely unlikely under legitimate traffic. False positives are uncommon. If you believe one fired, contact support with the pk_prefix from the webhook payload.

Customer support

For everything else, contact us:

For real-time integration support, your account manager can grant access to a private Slack channel — ask them.

Next steps

Developer Portal