Ghidul e disponibil deocamdată doar în engleză, ca documentația API.

Getting started

Voice is telephony through an API for sales and support teams, a 2Lines product. The agent clicks the customer’s number in the CRM: the platform rings the agent’s mobile, then the customer, from the company’s landline number. Inbound calls reach the right agent. Your CRM hears about every step through signed webhooks and gets the recording at the end.

This guide takes you from the first key to the first call, then to production. You integrate on staging first, which only calls your test numbers; then you move to production with new keys.

The full reference, with every endpoint, field, error code and event, is the API documentation: staging and production.

How the platform is organised

Level Key What it holds
Partner (you, if you run a CRM with several customers) psk_live_… / psk_test_… your tenants, their API keys, webhooks and route endpoints (/v1/tenants/…)
Tenant (a company: one of your customers) sk_live_… / sk_test_… its agents, lines (phone numbers), queues, webhook, calls and recordings, kept apart from the other companies
Agent none a person who makes and takes calls: the platform rings the agent’s mobile first, then connects the customer

Every request carries Authorization: Bearer <key>. Keys are per environment and shown only once, when created: store them as secrets.

Environments

Environment Base URL Keys
Staging (sandbox) https://voice-api-staging.2l.ro *_test_*
Production https://voice-api.2l.ro *_live_*

Integrate against staging first. It places real calls, but only to phone numbers on an allowlist kept by us (send us your test numbers). Each environment serves these docs at /v1/docs and the schema at /v1/openapi.json. The examples below use staging.

Step 1. Get your partner key

We create your partner organisation and hands over the partner key through a secure channel (never by plain email). A key can be restricted to a list of client IPs (ask us); without a list it is accepted from any IP, and a request from an IP outside the list gets 403 IP_NOT_ALLOWED.

Step 2. Check the partner key

curl https://voice-api-staging.2l.ro/v1/tenants -H "Authorization: Bearer $PARTNER_KEY"
# → {"data": [...], "next_cursor": null}   your tenants

Step 3. Create a tenant

curl -X POST https://voice-api-staging.2l.ro/v1/tenants \
  -H "Authorization: Bearer $PARTNER_KEY" -H "Content-Type: application/json" \
  -d '{"name": "Dealer One", "slug": "dealer-one"}'
# → {"tenant_id": "tn_…", …}

The slug is unique on the platform and is sent as tenant in every webhook. We allocate the tenant’s phone numbers (lines): tell us which tenant needs which numbers.

Step 4. Create the tenant’s API key

curl -X POST https://voice-api-staging.2l.ro/v1/tenants/tn_…/api-keys \
  -H "Authorization: Bearer $PARTNER_KEY" -H "Content-Type: application/json" \
  -d '{"name": "crm"}'
# → {"key_id": "…", "api_key": "sk_test_…", …}   shown only once

A tenant can have two active keys at a time, so you can rotate without downtime: create the new key, deploy it, then revoke the old one (DELETE /v1/tenants/{tenant_id}/api-keys/{key_id}).

Step 5. Check the tenant key and its configuration

curl https://voice-api-staging.2l.ro/v1/ping -H "Authorization: Bearer $TENANT_KEY"     # which tenant
curl https://voice-api-staging.2l.ro/v1/lines -H "Authorization: Bearer $TENANT_KEY"    # its phone numbers
curl https://voice-api-staging.2l.ro/v1/queues -H "Authorization: Bearer $TENANT_KEY"   # queues for inbound calls

Step 6. Configure the webhook

With the tenant key, or with the partner key on PUT /v1/tenants/{tenant_id}/webhook:

curl -X PUT https://voice-api-staging.2l.ro/v1/webhook \
  -H "Authorization: Bearer $TENANT_KEY" -H "Content-Type: application/json" \
  -d '{"url": "https://crm.example.com/telephony/events"}'
# → {"secret": "whs_…", …}   shown only once

Verify every delivery with the secret (X-Signature, X-Timestamp; see Webhooks in the API documentation). Webhooks come from several IP addresses that can change: rely on the signature, not on an IP allowlist. Delivery is at least once, so deduplicate by event_id. Every attempt is listed by GET /v1/webhook-deliveries.

Step 7. Create the agents

curl -X POST https://voice-api-staging.2l.ro/v1/agents \
  -H "Authorization: Bearer $TENANT_KEY" -H "Content-Type: application/json" \
  -d '{"name": "Andrei Ionescu", "mobile": "+40722123456", "external_ref": "41",
       "default_line_id": "ln_…", "queues": ["q_…"], "status": "AVAILABLE"}'
# → {"agent_id": "ag_…", …}

Change availability with PUT /v1/agents/{agent_id}/status.

Step 8. Make the first call

Always send an Idempotency-Key: a retry after a timeout then never places a second call.

curl -X POST https://voice-api-staging.2l.ro/v1/calls \
  -H "Authorization: Bearer $TENANT_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"agent_id": "ag_…", "to": "+40700987654", "external_ref": {"lead_id": 612}}'
# → 201 {"call_id": "c_…", "status": "INITIATED"}

The platform calls the agent’s mobile; when the agent answers (and, if the tenant requires it, confirms with key 1), it calls the customer on the agent’s line and connects them. You receive call.created, call.agent_answered, call.answered and call.ended; GET /v1/calls/{call_id} returns the same state at any time, and GET /v1/calls/{call_id}/timeline shows every event with its delivery attempts.

Step 9. Download the recording

Calls with record (the tenant default) are recorded. After call.recording_ready:

curl -o call.mp3 https://voice-api-staging.2l.ro/v1/calls/c_…/recording -H "Authorization: Bearer $TENANT_KEY"

Keep your own copy: the platform deletes it after the tenant’s retention period (7 days by default). If the recording cannot be produced you receive call.recording_failed instead (see Recordings in the API documentation).

Step 10. Inbound calls (optional)

When a customer calls one of the tenant’s lines, the platform can ask your endpoint which agent should take the call (tenant key, or the partner key on PUT /v1/tenants/{tenant_id}/route-config):

curl -X PUT https://voice-api-staging.2l.ro/v1/route-config \
  -H "Authorization: Bearer $TENANT_KEY" -H "Content-Type: application/json" \
  -d '{"url": "https://crm.example.com/telephony/route"}'

The request comes from 63.189.116.235, is signed with the webhook secret and must be answered within 1.5 s (see Inbound calls in the API documentation). Without it the platform still routes inbound calls: to the last agent who talked to the caller, then to the queue. Working hours, menus and queues are set up by us: send us, per tenant, the schedule, the menu options and which agents take which queue.

Step 11. Go live

When the integration works on staging, we hand over the production partner key (psk_live_…) and allocate the production numbers. Repeat steps 3 to 7 on https://voice-api.2l.ro with your production webhook and route URLs.

When you contact us about a request, quote its X-Request-Id response header.