Credentials & Resources
Register the provider connections your agents use — the same connections you see on the Connections page — and find out what each one actually gives you: the phone numbers or email senders behind it, and which agent is using each one.
| Operation | Endpoint | Scope |
|---|---|---|
| Register a connection | POST /api/v1/credentials | credentials:write |
| List connections | GET /api/v1/credentials | credentials:read |
| Get one connection | GET /api/v1/credentials/{id} | credentials:read |
| List a connection's resources | GET /api/v1/credentials/{id}/resources | credentials:read |
Registering a connection
bash
curl -X POST "https://<your-workspace>-api.perfox.ai/api/v1/credentials" \
-H "Authorization: Bearer sk_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Plivo — India numbers",
"type": "plivo",
"description": "Main support line",
"config": { "auth_id": "…", "auth_token": "…" }
}'| Field | Values |
|---|---|
name | 1–200 characters |
type | The provider, e.g. plivo, aws_ses, meta_whatsapp, google_sheets |
description | Optional |
config | The provider's own fields — the same ones its form asks for on the Connections page |
The response is 201 with the stored connection. A new connection starts as not_configured; open it on the Connections page and run its test to confirm it works.
Secrets are never returned
No read ever returns a secret. Every connection comes back as:
| Field | Meaning |
|---|---|
id, name, type, description | As registered |
status | connected, error, not_configured or pending_verification |
config_fields | The names of the config keys that are set — never their values |
last_tested | When it was last tested, or null |
created_at / updated_at | Timestamps |
config_fields lets you confirm a registration worked (for example that auth_token was stored) without anyone being able to read the value back. GET /api/v1/credentials returns up to 200 connections, newest first.
A connection is not its resources
GET /api/v1/credentials/{id} answers "is this provider connected". The resources call answers the question you usually have next: which numbers does that account give me, what can each one do, and who is using it.
bash
curl "https://<your-workspace>-api.perfox.ai/api/v1/credentials/{id}/resources" \
-H "Authorization: Bearer sk_…"json
{
"data": [
{
"identifier": "+918000000001",
"label": "+918000000001 (Plivo)",
"channel": "phone",
"capabilities": ["voice"],
"provider": "plivo",
"status": "active",
"assigned_agent": { "id": "…", "name": "Sales Assistant" }
},
{
"identifier": "+918000000002",
"label": "+918000000002 (Plivo)",
"channel": "whatsapp",
"capabilities": ["whatsapp"],
"provider": "plivo",
"status": "active"
}
]
}An unknown id returns 404 not_found.
The channel is the purpose
channel | What the identifier is for |
|---|---|
phone | Voice calls |
sms | Text messages |
whatsapp | |
email | Email sending |
Agent assignment
When an agent claims an identifier, the entry carries assigned_agent with that agent's id and name.
When nothing claims it, the field is absent rather than null — an unassigned spare number is a normal state, not missing data. One identifier belongs to at most one agent (the rule the agent builder enforces), so this is a single value and not a list.
The assignment is read from the agents themselves at request time rather than from a stored copy, so a number you rebind in the builder is correct here immediately.