# Enroll Your Own Numbers

> Add numbers you own to the masking pool and choose how each one routes — internal mapping or a dynamic routing webhook. List, enroll, configure and release numbers via the API.

Source: https://edesy.in/docs/number-masking/sessions/enroll-numbers

Masking allocates virtual numbers from a **pool** you enroll. Because one number [safely serves many concurrent sessions](https://edesy.in/number-masking/features/number-pooling), you only need to add numbers as real concurrency grows — the [Create a Session](https://edesy.in/docs/number-masking/sessions/create-session) call returns `422` when every enrolled number is busy for the requested parties, which is your signal to enroll more.

## List numbers

```
GET /masking/numbers
```

Returns the numbers available in your pool.

```
GET /masking/numbers/enrolled
```

Returns your enrolled numbers together with their routing configuration.

```bash
curl https://voice-api.edesy.in/v1/masking/numbers/enrolled \
  -H "Authorization: Bearer vp_YOUR_API_KEY"
```

## Enroll a number

```
POST /masking/numbers/enroll
```

Binds a number you own into the masking pool so it can carry masked calls.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `phone_number_id` | string (UUID) | Yes | The id of a number on your account to enroll. |
| `label` | string | No | A human-friendly label (max 120 characters). |

```bash
curl -X POST https://voice-api.edesy.in/v1/masking/numbers/enroll \
  -H "Authorization: Bearer vp_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "phone_number_id": "a1b2c3d4-...", "label": "Marketplace pool #1" }'
```

## Configure routing

```
PATCH /masking/numbers/:id/routing
```

Choose how a number resolves its target on each call.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `routing_mode` | string | Yes | `internal` (use session/mapping routing) or `webhook` (ask your endpoint per call). |
| `webhook_url` | string | No | Your HTTPS endpoint, required when `routing_mode` is `webhook`. |
| `webhook_method` | string | No | `POST` (default) or `GET`. |
| `webhook_secret` | string | No | Signing secret for `X-Edesy-Signature`. Leave blank to keep the existing one. |
| `fallback_internal` | boolean | No | On webhook failure, fall back to internal routing instead of rejecting. |
| `answer_on_bridge` | boolean | No | When true, the caller hears real ringback and the call is not billed until the other party answers. Omit to keep the current setting. |
| `label` | string | No | Update the number's label. |

```bash
curl -X PATCH https://voice-api.edesy.in/v1/masking/numbers/NUMBER_ID/routing \
  -H "Authorization: Bearer vp_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "routing_mode": "webhook",
    "webhook_url": "https://api.yourapp.com/edesy/route",
    "webhook_secret": "whsec_supersecret",
    "fallback_internal": true
  }'
```

For the request and response shape of the routing webhook itself, see [Dynamic Routing Webhook](https://edesy.in/docs/number-masking/sessions/dynamic-routing). To validate it, use `POST /masking/numbers/:id/routing/test`.

> The webhook signing secret is never returned by the API — responses expose only a `has_webhook_secret` flag so you can tell whether one is set.

## Release a number

```
DELETE /masking/numbers/:id
```

Removes a number from the masking pool. In-flight sessions on that number stop routing.

## Related

- [Number Pooling &amp; Concurrency](https://edesy.in/number-masking/features/number-pooling)
- [Dynamic Routing Webhook](https://edesy.in/docs/number-masking/sessions/dynamic-routing)
- [Create a Session](https://edesy.in/docs/number-masking/sessions/create-session)
