Buy a phone number

Buy a phone number for this sub-account. This costs money: the purchase is charged to the wallet (your saved card may be charged to cover it), and the number renews and is billed every 30 days until released. Optionally assign it to an agent in the same call.

POST https://api.centerfy.ai/webhooks/inbound/phone-numbers/purchase

Headers

HeaderRequiredValueDescription
x-api-keyYesyour sub-account API key (cfy_…)Authenticates the request; or use Authorization: Bearer <key>.
Idempotency-KeyYesa unique value per purchase, e.g. a UUID1–255 printable characters, no spaces; scoped to your sub-account. Retrying with the same key and the same body after a purchase finished returns the original response (with an Idempotent-Replayed: true header) without buying or charging again. If the request failed before anything was charged, the key is freed and can be retried.

Body parameters

NameTypeRequiredDefaultDescription
phone_numberstringYes—A US local number in E.164 format, e.g. +14155550123, as returned by Search available numbers.
agent_idstring (uuid) | nullNo—Agent in this sub-account to assign the number to after purchase.

Request body

{
  "phone_number": "+14155550123",
  "agent_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
}

Example

curl -X POST "https://api.centerfy.ai/webhooks/inbound/phone-numbers/purchase" \
  -H "x-api-key: $CENTERFY_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "phone_number": "+14155550123",
  "agent_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
}'
import { CenterfyClient } from "@centerfy/sdk";
import { randomUUID } from "node:crypto";

const centerfy = new CenterfyClient({ apiKey: process.env.CENTERFY_API_KEY! });

const result = await centerfy.phoneProvisioning.purchase({
  "phone_number": "+14155550123",
  "agent_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
}, { idempotencyKey: randomUUID() });
console.log(result);
centerfy phoneProvisioning purchase '{"phone_number":"+14155550123","agent_id":"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"}'
# the CLI adds a fresh Idempotency-Key for you

MCP tool: centerfy_phone_numbers_purchase (see MCP server)

Response

{
  "status": "success",
  "purchased": true,
  "phone_number": {
    "id": "9f8e7d6c-5b4a-4392-8170-6f5e4d3c2b1a",
    "phone_number": "+14155550123",
    "purchased": true,
    "agent_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
    "is_active": true,
    "purchased_at": "2026-10-06T10:00:00.000Z",
    "next_billing_date": "2026-11-05T10:00:00.000Z"
  },
  "agent_assignment": {
    "assigned": true,
    "agent_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
  }
}

Errors

  • 409 — if the key was already used with a different body, or a request with that key is still in progress.
  • 402 — if the wallet balance is insufficient (nothing charged).
  • 403 — if the sub-account’s phone number limit is reached (with current and max) or the API key has no owning user.
  • 404 — if the agent is not in this sub-account.
  • 409 — if the number is not available to buy.
  • 502 — if availability or billing could not be confirmed (not charged), or the order failed after charging — the response says whether the charge was refunded (refunded: true/false); if it says contact support, do not retry.
  • 503 — if purchasing is not available.

Notes

Returns 201. agent_assignment is present only when agent_id was sent; if assignment fails the number is still bought (assigned: false with an error) — retry with POST /webhooks/inbound/phone-numbers/:id/agent. Idempotency: always send a new Idempotency-Key per purchase and reuse it only to retry that same purchase. Same key + same body after completion replays the stored response (201 or 502) with Idempotent-Replayed: true and no new charge. Other errors: 400 if the Idempotency-Key header is missing or invalid, phone_number is not a US E.164 number, or agent_id is not a UUID.

© 2026 Centerfy AI. All rights reserved.