Skip to content
RelationsAI
API fundamentals

Security practices

This page collects the practices that keep your integration and your customers' data safe: key handling, least privilege, network restrictions, webhook verification and data handling. A live key can place real calls to real people and spend your workspace's balance, so treat it like a payment credential.

Keys

  • Server-side only. Never put an API key in a web page, mobile app, desktop app, browser extension or anything else you ship. The API refuses live keys sent from browsers (live_key_not_allowed_in_browser), but a key in shipped code is exposed whether or not the API accepts it from there.
  • Least privilege. Give each key only the scopes its system needs (see API keys). A reporting job does not need calls:write; a contact sync does not need transcripts:read.
  • One key per system and environment. Then you can rotate or revoke one without touching the others, and the console's Last used and request counts tell you which system did what.
  • Always an expiry. Live keys always expire; give test keys an expiry too unless they are only on your own machine. Track api_key.expires_at from GET /v1/workspace and rotate before it.
  • Store in a secret manager or deployment-provided environment variables. Never in source control, container images, logs, crash reports, analytics, URLs or tickets.
  • Never log credentials. Redact the Authorization header in your HTTP client's logging and in proxies. Log the key id (key_...) and the request id instead.
  • Keys follow people. A key stops working when its creator leaves the workspace, and loses scopes when the creator's role is reduced. Create production keys from an account that will stay, and replace keys before someone leaves.

If a key is exposed

  1. In the console, rotate the key with the grace period Immediately, or revoke it. Either takes effect at once.
  2. Deploy the replacement key.
  3. Review what the key did: its Last used time and address in the console, and the calls, campaigns and contacts changed in that mode around that time.
  4. If live calls may have been placed by someone else, write to support@relationsai.com with the key id (never the key itself) and the time window.

Restrict where keys work

If your servers have fixed outbound addresses, ask a workspace admin to set an IP allowlist in the console security settings. API requests from other addresses are then refused with ip_not_allowed, so a leaked key is useless elsewhere. If the allowlist cannot be checked, the API refuses the request rather than letting it through.

Test before live

  • Develop, test and run CI with test keys. Test mode never dials anyone or charges anything.
  • Keep live keys out of development machines, CI and staging.
  • At startup, check livemode from GET /v1/workspace against the environment you expect, and refuse to run if they differ.
  • Use the fictional test numbers (+12025550100 to +12025550106) in tests and fixtures, never real people's numbers.

Webhooks

  • Verify every signature with the endpoint's secret, over the raw body, in constant time, and reject events whose t is more than 5 minutes off. See Verifying webhook signatures.
  • Deduplicate by event id; deliveries are at least once.
  • Check livemode and only act on events of the mode the endpoint is meant for.
  • Treat the payload as a notification. For actions that matter (billing, follow-ups), read the object from the API before acting.
  • Keep the secret secret: store it like an API key, and rotate it if it may have been exposed: with grace_period_hours: 0 the old secret stops signing at once. A replayed create or rotate response shows secret: null, so the first response is the only copy; if you lose it, rotate again.
  • Answer fast and process later, so slow work cannot cause timeouts and redelivery storms.

Call data

Transcripts, recordings, analysis and contact data contain personal data about the people your agents call. The API returns them in full to your workspace, so protecting them in your systems is your responsibility.

  • Restrict access to the systems and people that need it, and only grant transcripts:read and recordings:read to keys that need them.
  • Recording links are credentials. The url from GET/calls/{call_id}/recording works without an API key until it expires (about 15 minutes). Do not log, store or forward it; ask for a fresh link when you need one. An expired link answers media_link_expired. It also stops working (404) as soon as the API key that obtained it is revoked or expires, loses recordings:read, or its creator leaves the workspace. Revoking a leaked key therefore also cuts off the recording links it obtained.
  • Keep data only as long as you need it, and delete it from your systems according to your retention policy.
  • No secrets or sensitive data in metadata. It is stored and returned as sent; use your own ids instead.
  • Keep consent and the do-not-call list accurate. Record consent only when the person really gave it, record withdrawals promptly, and add do-not-call requests as soon as you receive them. See Consent and do-not-call.

Your own endpoints and logs

  • Serve your webhook endpoint over HTTPS with a valid certificate.
  • Do not echo request bodies or headers into error pages.
  • When you write to support, follow Support: never send keys, full Authorization headers, webhook secrets, customer data or transcripts.

Reporting a problem

Report a suspected security issue in the API or these docs to support@relationsai.com with "Security" in the subject. Describe what you found and how to reproduce it, without including real customer data or live credentials.