# Two-Way Sessions

> Bind two real numbers to one virtual number for a limited time. Either party dials the virtual number and is bridged to the other — routing is decided by who is calling, so the same number works in both directions.

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

A **session** binds two real numbers to a single **virtual number** for a limited lifetime. Either party can call that virtual number and is bridged to the other — routing is decided by who is calling, so the same number works in both directions. Neither party ever sees the other's real number; both see the virtual number.

This is the primitive behind marketplace, ride, delivery, and booking privacy: when an order is created, you create a session and hand the virtual number to both parties; when the order is done, the session expires and the number is freed for reuse.

## How it differs from click-to-call

The [Initiate a Call](https://edesy.in/docs/number-masking/api-reference/initiate-call) endpoint (`POST /masking/calls`) is **outbound**: we dial Party A, then bridge Party B. A session is **inbound**: you get a virtual number back and *either* party dials it whenever they want, as many times as you allow, until the session expires.

| | Click-to-call (`/masking/calls`) | Session (`/masking/sessions`) |
|---|---|---|
| Who starts the call | The platform dials both parties | Either party dials the virtual number |
| Number of calls | One bridged call | Many, until expiry or `max_calls` |
| Lifetime | Single call | Minutes to 30 days |
| Best for | "Call now" buttons | Ongoing order/ride/booking privacy |

## Lifecycle

1. **Create** a session with two numbers — get a `virtual_number` back. See [Create a Session](https://edesy.in/docs/number-masking/sessions/create-session).
2. **Share** the virtual number with both parties.
3. Either party **calls** the virtual number; we bridge them to the other party. Both see the virtual number as caller ID.
4. **Manage** the session — extend its expiry, pause/resume routing, or read its status. See [Manage a Session](https://edesy.in/docs/number-masking/sessions/manage-session).
5. **End** the session (or let it expire). The virtual number stops routing and returns to the pool.

## Idempotency

Create is **idempotent on your `reference`** (any external id — an order, ride, or ticket id). Repeating the call for an active reference returns the existing session instead of allocating another number, so retries and duplicate events are safe.

## Related

- [Create a Session](https://edesy.in/docs/number-masking/sessions/create-session)
- [Manage a Session](https://edesy.in/docs/number-masking/sessions/manage-session)
- [Dynamic Routing Webhook](https://edesy.in/docs/number-masking/sessions/dynamic-routing) — decide targets per call from your own server
- [Event Webhooks](https://edesy.in/docs/number-masking/sessions/event-webhooks) — receive session and call lifecycle events
- [Enroll Your Own Numbers](https://edesy.in/docs/number-masking/sessions/enroll-numbers)
