Integration Guide
This guide goes from your first call to a production integration. It explains how to send a request, how to read the response, and what changes when you move from demo numbers to real ones.
Before you start
Once your onboarding is complete, the Plumma console gives you:
- An API key for your organization. You can copy it once only, so store it in a secrets manager straight away (see Authentication).
-
An application, with its application id in the format
NN-XXXXXXX-APP. Every call names the application it belongs to. - The Sandbox page, where you can send commands to demo numbers with a few clicks.
Optionally, an HTTP client such as Postman, Insomnia or cURL.
Your first call
The quickest check is a single command sent to a demo number. Demo numbers return synthetic but consistent data, and they are never charged.
From the console Sandbox
Open the Sandbox page, pick a demo number, select one or more commands and send. The page shows the response, the exact payload that was sent and the equivalent cURL command, which you can copy into your own code.
From your own code
There is one endpoint. Every call is a POST with a JSON
body and two authentication headers. There is no
Authorization: Bearer header.
curl -X POST "https://connect.plumma.it/services/api" \
-H "Content-Type: application/json" \
-H "x-plumma-connect-api-key: YOUR_API_KEY" \
-H "x-plumma-connect-app-id: YOUR_APP_ID" \
-d '{
"number": "DEMO_NUMBER",
"commands": ["sim_swap"]
}'
The body has two required fields:
-
number: the phone number in international format, with or without the leading+(for example+447808226974). It is checked against the numbering plan of its country, and an invalid number is rejected with400. -
commands: a non-empty list of command names, each listed once. A name that is not a Plumma® Connect command is not run and not charged, and the response names it instatus_message.
If the response's status_message ends with
This response is for demo purpose only, your key, your
application id and your payload are all correct.
To ask for more, add commands to the same list. One request, one response:
{
"number": "DEMO_NUMBER",
"commands": ["sim_swap", "current_carrier"]
}
A demo number answers every command you ask for. A real number may not: what can be served depends on the number's country and its operator. The next section explains how the response shows this, command by command.
Reading a response
Every response has a numeric status and a plain-language
status_message. Use status in your code: the
wording of status_message can change.
| status | Meaning |
|---|---|
0 | Every command you asked for was served. |
4 | Partial reply: some commands were served and others were not. |
2 | None of the commands you asked for is available in the number's country. |
3 | None of the command names you sent is recognized. |
5 | The request could not be completed. |
With several commands in one request, expect status: 4
sometimes. It is a signal to look inside the response, not an error.
Here is a real number in Italy, asked for two commands, where only one
is available:
{
"number": "+39XXXXXXXXXX",
"status": 4,
"status_message": "Response from one supplier - Commands [age_verification] not available in [IT]",
"simswap": {
"risk_indicator": 0
},
"version": "..."
}
Read the response one command at a time:
-
A command that was served has its own block in the response. Here that
is
simswap, the block ofsim_swap. -
A command that was not served has no block at all. Fields are left out,
never set to
null. -
The
status_messagenames the commands that were not served, and says why: not available in that country, sent to an operator that returned no data, or not recognized.
Inside a block, a negative value is still an answer from the operator.
For example, risk_indicator: -1 means "this operator holds
no data for this number". Each field's meaning is documented in the API
reference.
When something goes wrong
| You get | What to do |
|---|---|
HTTP 400 |
The number or the payload is not valid. The detail
field says what is wrong. Fix the request: retrying it unchanged
will fail again. |
HTTP 401 / 403 |
A problem with the key or the application. See Authentication. |
HTTP 429 |
Too many requests. Wait for the number of seconds given in the
Retry-After header, then retry. |
status: 2 |
Retrying will not change the result. If you expected coverage in that country, contact support. |
status: 3 |
Check the spelling of the command names against the API reference. |
status: 5 or HTTP 5xx |
Usually temporary. Retry after a short wait, with an increasing delay between attempts. |
Every response, including errors, carries an X-Correlation-ID
header. Include it whenever you contact support about a call.
Getting into the habit of reading responses this way now pays off later. In production you are charged only for the commands that were served. A command that was not served costs nothing. See Billing.
Setting up your environment
Once your first calls work, move them into your usual tools. The API is described in an OpenAPI 3.1 descriptor that Postman and Insomnia can import. You get the endpoint, the request schema and example requests ready to run.
There is a single endpoint for every call:
https://connect.plumma.it/services/api. No separate test
host exists. A demo number gives demo data and a real number gives real
data, so moving from one to the other means changing the number, not the
server. In your Postman or Insomnia environment, keep the key and the
application id as variables. The base URL does not need to change.
Rate limits
Each key can send up to 900 requests per minute, about 15 per second on
average. The limit is counted over a one-minute window. Above it, calls
are refused with 429 and a Retry-After header.
If you need more, contact Plumma.
From demo numbers to real numbers
Take your time. Demo responses have exactly the same structure as real ones, so a fully tested integration needs no code change to go live. Only the data changes: from synthetic to real.
To call real numbers you need:
- A paid plan. You can choose and buy it from the console. Real numbers are charged per served command (see Billing).
-
Your organization approved and your key enabled for your
application. Plumma does both. Until then, calls for that
application are refused with
403.
Demo numbers keep working after you go live, with the same key, so you can keep them in your regression tests. They are never charged.
Next steps
- Authentication: headers, key validity, copying and regenerating keys.
- Billing: what is charged, how to read
status, coverage by country. - API reference: every command, request field and response field.