API keys authenticate requests to api.hookdeploy.dev. Create them in the dashboard, use them in scripts and CI, and rotate them regularly.
Every key belongs to one organization. What it can do depends on two independent checks:
- The key’s access mode — full access, or a custom list of scopes
- The creator’s role — a key cannot grant more than that member is allowed to do
A scoped key that holds endpoints:write still fails if the creator’s role lacks endpoints.create. A full-access key skips the scope check and is gated only by the creator’s role — the same behavior keys had before scoping shipped.
Creating an API key
Creating your own key requires api_keys.manage_own. Managing keys created by other members requires api_keys.manage.
- Go to Settings → API Keys in your organization
- Click Create API key
- Enter a name (e.g.
CI pipeline,Zapier) - Choose Full access (default) or Custom scopes
- Click Create key
The full key is displayed once:
hd_live_us_a1b2c3d4e5f6...
Copy it immediately. After you close the dialog, only the prefix is visible. The full key cannot be recovered.
Keys use the form hd_live_{region}_{random}. The region segment matches the organization that owns the key.
Full access vs custom scopes
Full access is the default. The scope picker stays hidden. The key can call any route the creator’s role allows. Existing keys created before scoping shipped are full access and stay that way until an admin edits them.
Custom scopes reveals a grouped checklist. The key can only call routes covered by the checked scopes, and only if the creator’s role also allows the action.
The dashboard blocks creating a custom-scope key with nothing checked (“Select at least one scope, or choose Full access”). A key with zero scopes would authenticate but could not call scoped routes.
Read + Notify preset
Read + Notify (recommended for integrations) pre-checks six scopes and leaves them editable:
endpoints:readrequests:readdestinations:readincidents:readsubscriptions:readsubscriptions:write
That combination is enough to list endpoints and destinations, read captured traffic and incidents, and manage webhook / incident subscriptions — the usual Zapier or Make.com setup. It does not include write access to endpoints, destinations, incidents, members, or request replay.
Available scopes
| Scope | Name | What it unlocks |
|---|---|---|
endpoints:read | Read endpoints | List endpoints |
endpoints:write | Write endpoints | Create, edit, and delete endpoints |
requests:read | Read requests | View captured requests, forward response bodies, and subscription sample payloads |
requests:replay | Replay requests | Replay a captured request |
destinations:read | Read destinations | List and get saved destinations, and list destinations attached to an endpoint |
destinations:write | Write destinations | Create HTTPS or agent destinations |
subscriptions:read | Read subscriptions | List webhook and incident subscriptions; sample payloads also need requests:read |
subscriptions:write | Write subscriptions | Create and delete webhook and incident subscriptions |
incidents:read | Read incidents | List, get, sample, and recent incidents |
incidents:write | Write incidents | Update incident status and replay incident failures |
members:invite | Invite members | Invite organization members |
members:manage | Manage members | Deactivate and reactivate members |
usage:read | Read usage | View organization usage |
requests:replay requires requests:read. Checking replay in the dashboard auto-checks read and prevents unchecking it while replay stays selected. The database also rejects a scoped key that has replay without read.
Listing endpoints (GET /v1/endpoints) and listing subscriptions require only the matching read scope. They are not also gated on the creator’s endpoints.view or a subscriptions permission.
Creating an agent destination requires destinations:write plus both endpoints.edit and agents.assign_destination on the creator’s role. Creating an HTTPS destination requires destinations:write and endpoints.edit only.
Routes that do not use scopes
These public routes accept any valid key for the organization. They do not check a scope:
GET /v1/meGET /v1/health
A scoped key with no other scopes can still call those routes. They still require a live, unrevoked, unexpired key.
GET /v1/subscriptions/sample/:endpointId requires both subscriptions:read and requests:read (scope-only). GET /v1/endpoints/:id/destinations requires destinations:read and destinations.view.
Using an API key
Pass the key in every API request:
curl -s "https://api.hookdeploy.dev/v1/health" \
-H "Authorization: Bearer hd_live_YOUR_KEY"
Missing or invalid keys return 401 unauthorized. A valid key that lacks the required scope or role permission returns 403 forbidden.
Scope and role checks can take up to 60 seconds to reflect a change if cache invalidation does not complete. Revocation still applies on subsequent authentication checks.
Editing scopes
Changing a key from full access to custom scopes — or changing the checked scopes — requires api_keys.manage. Members who can only create their own keys (api_keys.manage_own) do not see Edit scopes. That is intentional: creating a key does not grant the right to change its scopes later.
Admins can switch any key between full access and custom scopes. Existing full-access keys are not converted automatically.
Key storage
HookDeploy stores API keys as one-way hashes rather than plaintext. On creation:
- HookDeploy generates a random key with prefix
hd_live_ - Shows you the full key once
- Stores only the hash, a display prefix, the access mode, and any custom scopes
If HookDeploy’s database is compromised, keys cannot be reversed from hashes.
Security best practices
Do not commit keys to git. Use environment variables:
export HOOKDEPLOY_API_KEY="hd_live_YOUR_KEY"
curl -s "https://api.hookdeploy.dev/v1/endpoints" \
-H "Authorization: Bearer $HOOKDEPLOY_API_KEY"
In CI (GitHub Actions example):
- name: Check HookDeploy usage
env:
HOOKDEPLOY_API_KEY: ${{ secrets.HOOKDEPLOY_API_KEY }}
run: |
curl -s "https://api.hookdeploy.dev/v1/usage" \
-H "Authorization: Bearer $HOOKDEPLOY_API_KEY"
Prefer custom scopes for integrations. Use the Read + Notify preset for Zapier, Make.com, and similar subscribers instead of a full-access key.
Use separate keys per environment. Create one key for CI, one for local dev, one for production automation. Revoke individually without affecting others.
Set expiration dates when creating keys for temporary access (e.g. contractor access for 30 days). Expired keys return 401 unauthorized.
Revoking a key
- Go to Settings → API Keys
- Open the key’s actions menu and click Revoke
- Confirm
Revocation takes effect for subsequent API authentication checks.
Revoked keys cannot be un-revoked. Create a new key instead.
Key rotation
To rotate without downtime:
- Create a new API key (copy the same scopes if the old key was scoped)
- Update your environment variables / CI secrets with the new key
- Verify the new key works (
GET /v1/health) - Revoke the old key
There is no grace period — old and new keys work simultaneously until you revoke the old one.
Audit logging
API key creation and revocation are recorded in the audit log. Each entry includes the actor, key name, and timestamp.
Backward compatibility
Keys created before scoping shipped are full access. They keep working without changes. Full access remains the default when you create a new key and do not open the scope picker.
A full-access key is still limited by the creator’s live role. Scoping never expands what that role can do; it only narrows a key further.
Next steps
- API overview — Authentication, routes, errors, and pagination
- Endpoints API — First API call after creating a key
- Roles & permissions — Who can manage keys
- Members — Roles used when inviting teammates
- Make.com — Scoped keys for scenario subscriptions
- Zapier integration — Scoped keys for Zapier subscriptions