Signals Docs
Getting started

Authentication

Signals has two APIs, and each has its own credential:

APIBase URLCredentialHow you send it
Signals APIhttps://api.signals.pressone.africa/v1API keyAuthorization: Bearer <key>
Calls API (Twilio-compatible)https://api.signals.pressone.africa/2010-04-01AccountSid and auth tokenHTTP Basic

The two credentials are not interchangeable. The Signals API refuses a voice auth token, and the Calls API refuses an API key.

API keys

An API key is a secret string that lets your server call the Signals API on behalf of your organization. Each key carries a role and a list of scopes, which together decide what it may do. A key can also be restricted to one subaccount.

Key format

An API key looks like this:

Code
sk_live_KQ7M3XPA2VDF_9f3c1e8a7b2d4f6091c5e3a7d8b0f2e4

It has three parts, separated by underscores:

PartExampleMeaning
Prefixsk_liveMarks the string as a Signals secret key. There is no test mode, so every key is live.
Public IDKQ7M3XPA2VDF12 characters from A to Z and 2 to 7. The console shows it so you can tell keys apart. It is not secret.
Secret9f3c1e8a7b2d4f6091c5e3a7d8b0f2e432 lowercase hexadecimal characters. Only you hold it.

A voice auth token also starts with sk_live_, but it has no second underscore: it is sk_live_ followed by 32 letters and digits. If the Signals API answers 401 to a credential you are sure is current, check that you did not paste the voice auth token.

Create a key

Members with the Admin or Engineer role create keys in the console.

  1. Open the Signals console and choose API keys in the Develop section of the sidebar.
  2. Start a new key.
  3. Enter a name that says where the key is used, such as billing-sync.
  4. Choose a role and the scopes the key needs. The console offers only the roles and scopes you are allowed to grant.
  5. Optionally, restrict the key to one subaccount and choose when it expires.
  6. Copy the key and store it in a secrets manager.

The console shows the full key once, at creation. Signals stores only a hash of the secret part, so nobody can show you the key again. If you lose it, rotate the key or create a new one.

Send a key

Send the key in the Authorization header with the Bearer scheme:

TerminalCode
curl https://api.signals.pressone.africa/v1/projects \ -H "Authorization: Bearer $SIGNALS_API_KEY"
JSONCode
{ "data": [ { "id": "prj_0192a4c7-5e1b-7d3f-9a28-6c4e8b1f2d07", "name": "Production", "status": "active", "billing_account_id": "0192a4c6-9d2e-7b31-8f45-a1c3e5d7b902", "billing_assignment_revision": 1, "billing_effective_from": "2026-09-01T00:00:00Z", "currency": "NGN", "pending_payer": null } ] }

Send exactly one Authorization header, with one space between Bearer and the key. The scheme name is case-insensitive. A missing, malformed, unknown, expired, rotated-out or revoked key gets the same answer:

Code
HTTP/1.1 401 Unauthorized Content-Type: application/problem+json X-Request-ID: req_0192b7e93c4f7a2e9d1b6c8f0a5e3d27 { "type": "https://signals.pressone.africa/problems/unauthenticated", "title": "Unauthorized", "status": 401, "detail": "A valid bearer credential is required.", "code": "unauthenticated", "request_id": "req_0192b7e93c4f7a2e9d1b6c8f0a5e3d27" }

Signals records when each key was last used, to the minute. The console shows it in the key list, which helps you find keys nothing uses any more.

What a key can do

Three settings bound every key. A request must pass all three.

Role. A key has one of the four organization roles: org:admin, org:engineer, org:billing or org:viewer. A key never does more than a member with that role. You can grant only a role at or below your own: an Admin can create a key with any role, and an Engineer can create Engineer and Viewer keys.

Scopes. A scope names one kind of action, such as call_history:read. A key holds at least one scope, and each scope must be one its role allows. A request that needs a scope the key lacks is refused with 403. Common scopes:

ScopeAllows
organization:readReading the organization record.
call_history:readReading call records and their detail.
live_calls:readReading calls in progress.
call_diagnostics:readReading SIP ladders and media diagnostics.
service_configuration:readReading trunks, policies, numbers and voice applications.
service_configuration:writeCreating and editing trunks, policies and voice applications.
numbers:manageHolding, routing and releasing numbers.
numbers:orderBuying numbers.
billing:readReading balance, usage, rates and billing documents.
recordings:manageManaging recordings and retention.
developers:manageManaging webhook endpoints.
tests:manageRunning trunk tests.
subaccounts:readReading subaccounts and their limits.
subaccounts:writeCreating and changing subaccounts. Admin keys only.
audit:readReading the audit trail.

Some actions need a person signed in to the console, and no key can perform them: managing API keys, managing members, viewing or rotating the voice auth token, rotating webhook signing secrets and accepting recording consent.

Subaccount. A key restricted to a subaccount reaches only the resources of that subaccount. A key without a subaccount reaches its whole project, within its role and scopes. The subaccount must be in the key's project.

A key also belongs to the project it was created in.

Rotate a key

Rotating replaces a key with a new one without downtime. In the console, choose Rotate on the key's row and pick how long the old key keeps working: 24 hours, 1 hour or none. The overlap can be any whole number of hours from 0 to 24, and never more.

  • Signals creates a new key with the same name, role, scopes, subaccount and expiry, and shows it once.
  • The old key keeps working until the overlap ends, then stops. With an overlap of 0 it stops at once.
  • The old key's record shows when it stops in retires_at, and the new key records the key it replaced in rotated_from_id.

Deploy the new key everywhere during the overlap. A key that has already been rotated cannot be rotated again; rotate its replacement instead.

Revoke a key

Revoke a key when it leaks or is no longer needed. In the console, choose Revoke on the key's row, type the key name to confirm and give a reason, which is kept in the audit trail. Revocation takes effect immediately and cannot be undone. Requests that use the key then fail with 401.

Expiry

A key with an expiry date stops working at that time. A rotated key inherits its predecessor's expiry. Set an expiry for keys you hand to contractors or short projects.

Choosing a project

A project is the unit that owns your resources and pays for them; see Introduction. Most endpoints act on one project. Name it with the optional X-Project-ID header, set to the project's ID. A project ID is prj_ followed by a lowercase UUID, as GET /v1/projects returns it:

TerminalCode
curl https://api.signals.pressone.africa/v1/trunks \ -H "Authorization: Bearer $SIGNALS_API_KEY" \ -H "X-Project-ID: prj_0192a4c7-5e1b-7d3f-9a28-6c4e8b1f2d07"
SituationResult
The organization has one active project and you omit the headerSignals uses that project.
The organization has several projects and you omit the header400 with code project_context_required. The problem lists your projects in available_projects.
The header is not a project ID400 with code project_invalid.
The project does not belong to your organization404 with code project_not_found.

Today every organization has one active project, so you can leave the header out. Sending it anyway keeps your code working if you add a project later.

Calls API credentials

The Calls API is the Twilio-compatible API for Programmable Voice calls. It does not use API keys. It uses your voice account's credentials:

  • AccountSid: the public name of your voice account, AC followed by 32 lowercase hexadecimal characters, such as AC8d2e61f04a9b3c7e5d1f2a6b0c4e9d37.
  • Auth token: the voice account's secret.

Each project has one voice account. In the console, open Developers, then Voice Account: the AccountSid is shown with a copy button, and Show displays the auth token. Admins and engineers can view and rotate the token at any time; viewers and billing members cannot.

Rotating replaces the token in one step. The old token stops working when the change applies, usually within seconds. Update every client with the new token as soon as you rotate.

The auth token also signs the webhooks Signals sends you. See Request signatures.

Authenticate with HTTP Basic. The username is the AccountSid and the password is the auth token:

TerminalCode
curl -u "$SIGNALS_ACCOUNT_SID:$SIGNALS_AUTH_TOKEN" \ "https://api.signals.pressone.africa/2010-04-01/Accounts/$SIGNALS_ACCOUNT_SID/Calls.json"

The username must equal the AccountSid in the path. If the header is missing, is not Basic, or names a different account, Signals refuses the request before it reaches the voice platform:

JSONCode
{ "type": "https://signals.pressone.africa/problems/unauthenticated", "title": "Unauthorized", "status": 401, "detail": "Basic authentication with the AccountSid as the username is required.", "code": "unauthenticated", "request_id": "req_0192b7f03a1e7c5d8b2f4e6a9c0d1b37" }

A wrong or rotated auth token is rejected by the voice platform with 401 in Twilio's error format. An unknown or inactive AccountSid returns 404 with code voice_route_not_proxied.

The Calls API serves these resources:

MethodPath under /2010-04-01/Accounts/{AccountSid}
GET, POST/Calls.json
GET, POST, DELETE/Calls/{CallSid}.json
GET/Calls/{CallSid}/Recordings.json
GET/Calls/{CallSid}/Events.json
GET/Recordings/{RecordingSid}

Any other path returns 404 with code voice_route_not_proxied. See Moving from Twilio for parameter-level differences.

Keep credentials safe

  • Keep keys on your server. Never put an API key or auth token in a web page, mobile app, desktop app or anything else you ship to users. Anyone who has the file has the key.
  • Load keys from a secrets manager or environment variables. Never commit them to source control or write them to logs.
  • Use one key per service. A key named after the system that uses it can be rotated or revoked without touching anything else.
  • Grant the least access. Choose the lowest role and the fewest scopes that work, and restrict the key to a subaccount when the service serves one customer.
  • Rotate on a schedule and after staff changes. Use the overlap to deploy the new key before the old one stops.
  • Revoke at once if a key leaks. Then create a replacement and check the audit trail for requests you do not recognize.
Last modified on