> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rumik.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# phone numbers

> rent a number and connect it to an agent for inbound calls.

a rented number is a real phone number, provisioned through rumik, that an
agent answers. rent one from the inventory, connect it to a deployed agent,
and callers who dial it get the agent. the same number is the caller id when
that agent [places calls](/outbound-calls).

numbers are Indian (`+91`) for now. renting needs a business KYC — once, per
account — and is paid from your wallet: the monthly rent up front and the
carrier's per-minute cost of every call, on top of the agent's own charge.

## 1. see what renting needs

`GET /v1/phone-numbers/requirements` says whether the account may rent, which
documents the KYC needs, and whether a verified KYC is already on file.

```bash curl theme={null}
curl https://silk-api.rumik.ai/v1/phone-numbers/requirements \
  -H "Authorization: Bearer rk_live_•••••••••"
```

<ResponseField name="eligibility" type="object">
  `eligible` and, when false, a `reason`. `mandateRequired` is true for a
  pay-as-you-go account: renting needs an auto-pay mandate, set up in the
  dashboard's billing page, so rent and call charges can always be covered.
</ResponseField>

<ResponseField name="requirements.documentTypes" type="object[]">
  the KYC form. **every** listed type is required — for an Indian business
  that is a registration certificate and the GST certificate — each with the
  `requiredFields` to fill in alongside the file.
</ResponseField>

<ResponseField name="verifiedKyc" type="object | null">
  set once the carrier accepted a KYC for this account. further numbers reuse
  it: skip step 3's documents and send a plain JSON body.
</ResponseField>

<ResponseField name="autoPayMinimum" type="object">
  the auto-pay amount a pay-as-you-go account needs: rent plus a reserve, in
  nanos of the wallet's currency.
</ResponseField>

## 2. pick a number

`GET /v1/phone-numbers/available` searches the live inventory. filter by a
digit `pattern` (an area prefix like `8046`) or a `city`; page with `limit`
(max 20) and `offset`.

```bash curl theme={null}
curl "https://silk-api.rumik.ai/v1/phone-numbers/available?pattern=8046&limit=5" \
  -H "Authorization: Bearer rk_live_•••••••••"
```

```json theme={null}
{
  "items": [
    {
      "number": "918046800123",
      "e164": "+918046800123",
      "city": "Bangalore",
      "region": "Karnataka",
      "numberType": "local",
      "monthlyRentNanos": 236250000000,
      "setupNanos": 0,
      "voiceRateNanos": 743715000,
      "outboundRateNanos": 945000000,
      "outboundUnitSeconds": 30,
      "currency": "INR",
      "voiceEnabled": true
    }
  ],
  "totalCount": 42,
  "limit": 5,
  "offset": 0
}
```

amounts are **nanos** (billionths) of the wallet's currency: `236250000000`
nanos INR is ₹236.25 a month. `voiceRateNanos` is the inbound per-minute
carrier rate, `outboundRateNanos` the outbound one, billed per
`outboundUnitSeconds`.

## 3. rent it

`POST /v1/phone-numbers`. two shapes, depending on whether the account's KYC
is already verified.

<Tabs>
  <Tab title="first number (with documents)">
    `multipart/form-data`: a `data` field holding the JSON below, and the
    document files in `files`, one per entry of `documents`, in the same order
    (`pdf`, `jpeg` or `png`, up to 5 MB each).

    ```json data theme={null}
    {
      "requestedNumber": "918046800123",
      "searchFilters": { "pattern": "8046" },
      "endUser": {
        "name": "Acme Technologies Pvt Ltd",
        "email": "ops@acme.example",
        "address_line1": "12 MG Road",
        "city": "Bengaluru",
        "state": "Karnataka",
        "postal_code": "560001",
        "country": "IN"
      },
      "documents": [
        { "documentTypeId": "certificate_of_incorporation", "dataFields": { "registration_number": "U72900KA2020PTC123456" } },
        { "documentTypeId": "gst_certificate", "dataFields": { "gstin": "29ABCDE1234F1Z5" } }
      ]
    }
    ```

    ```bash curl theme={null}
    curl -X POST https://silk-api.rumik.ai/v1/phone-numbers \
      -H "Authorization: Bearer rk_live_•••••••••" \
      -F 'data=@rental.json;type=application/json' \
      -F 'files=@certificate.pdf' \
      -F 'files=@gst.pdf'
    ```

    `documentTypeId` values and the `dataFields` each needs come from step 1.
    `searchFilters` is the search the number came from, so a matching
    substitute can be bought if the number is taken meanwhile.
  </Tab>

  <Tab title="kyc already verified">
    a plain JSON body — the verified KYC on file is reused and the rental goes
    straight to purchase.

    ```bash curl theme={null}
    curl -X POST https://silk-api.rumik.ai/v1/phone-numbers \
      -H "Authorization: Bearer rk_live_•••••••••" \
      -H "Content-Type: application/json" \
      -d '{ "requestedNumber": "918046800123" }'
    ```
  </Tab>
</Tabs>

renting returns `201` with the rental. the first month's rent is taken from the
wallet right away, then the documents go to the carrier:

```json theme={null}
{
  "id": "019f7d21-3c5f-7e60-9b7c-8d9e0f1a2b3c",
  "status": "kyc_submitted",
  "requestedNumber": "918046800123",
  "number": null,
  "e164": null,
  "monthlyRentNanos": 236250000000,
  "prepaidNanos": 236250000000,
  "currency": "INR",
  "userAgentId": null,
  "timeline": [
    { "key": "prepaid", "label": "first month's rent deducted", "state": "done", "at": "2026-09-11T10:00:05Z" },
    { "key": "submitted", "label": "documents submitted", "state": "done", "at": "2026-09-11T10:00:06Z" },
    { "key": "verification", "label": "verification", "state": "active", "at": null },
    { "key": "purchase", "label": "number purchase", "state": "pending", "at": null },
    { "key": "active", "label": "number active", "state": "pending", "at": null }
  ],
  "createdAt": "2026-09-11T10:00:00Z",
  "updatedAt": "2026-09-11T10:00:06Z"
}
```

## 4. wait for it

verification takes the carrier a while. poll `GET /v1/phone-numbers/{id}`
(every few seconds is fine) and watch `status` and `timeline`:

| `status`                       | meaning                                                                    |
| ------------------------------ | -------------------------------------------------------------------------- |
| `funding`                      | the wallet could not cover the first rent; auto-pay is topping it up       |
| `kyc_submitted`                | documents are with the carrier                                             |
| `kyc_rejected`                 | the carrier refused them — `compliance.rejectionReason` says why; resubmit |
| `kyc_accepted`                 | approved; the number is being bought                                       |
| `purchasing`, `awaiting_funds` | buying, or settling a price difference                                     |
| `active`                       | yours. `number` and `e164` are set                                         |
| `past_due`                     | a renewal could not be charged; inbound still works, outbound does not     |
| `released`                     | given up, or withdrawn                                                     |

a rejected KYC is fixed with `POST /v1/phone-numbers/{id}/resubmit` —
multipart again, with `endUser`, `documents` and **every** file, since the
carrier replaces them wholesale.

## 5. connect it to an agent

`POST /v1/phone-numbers/{id}/agent` with the agent's UUID or handle. from then
on callers who dial the number get that agent, and
[`POST /v1/calls`](/outbound-calls) for that agent dials from it.

```bash curl theme={null}
curl -X POST https://silk-api.rumik.ai/v1/phone-numbers/019f7d21-3c5f-7e60-9b7c-8d9e0f1a2b3c/agent \
  -H "Authorization: Bearer rk_live_•••••••••" \
  -H "Content-Type: application/json" \
  -d '{ "agentId": "ua_fe3277d8" }'
```

only a **deployed** agent can take a number (`409 agent_not_deployed`). an
agent answers one number and a number one agent: connecting moves the number
off its previous agent. `"agentId": null` detaches. the agent's
`inboundPhoneNumber` shows the connection.

## renewals and charges

rent is charged again before each renewal (`nextRenewalAt`). a pay-as-you-go
account's auto-pay mandate tops the wallet up when it is short; if it cannot,
the number goes `past_due` and, past the renewal, telephony is switched off —
every number released and pending rentals withdrawn with their prepaid rent
refunded. the dashboard's usage page lists every rent, renewal and per-call
carrier charge.

## release

`POST /v1/phone-numbers/{id}/release` gives the number up. it is irreversible,
so the body must spell the number:

```bash curl theme={null}
curl -X POST https://silk-api.rumik.ai/v1/phone-numbers/019f7d21-3c5f-7e60-9b7c-8d9e0f1a2b3c/release \
  -H "Authorization: Bearer rk_live_•••••••••" \
  -H "Content-Type: application/json" \
  -d '{ "confirmNumber": "+918046800123" }'
```

a rental that never reached `active` is withdrawn instead and its prepaid
rent returned to the wallet.

## list

`GET /v1/phone-numbers` returns every rental on the account, released ones
included, with the same fields.

next: [sip trunks](/sip-trunks).
