DIDfarm
  • Numbers
  • Trunks
  • Messaging
  • Connect
  • Pricing
  • Coverage
  • Help
🇬🇧 EN 🇳🇱 NL 🇩🇪 DE 🇫🇷 FR 🇪🇸 ES 🇧🇷 PT 🇸🇦 AR 🇨🇳 ZH 🇯🇵 JA 🇮🇳 HI
Sign in Get a Number
← Help Center
On this page
Overview Authentication Provision Numbers Create SIP Trunks Send Messages Billing per Client Webhooks Code Examples FAQ

Connect API Integration Guide

Connect · 12 min read API Integration Developer
Build on DIDfarm programmatically. This guide covers authentication, number provisioning, SIP trunk management, messaging, billing queries, and webhooks — everything you need to integrate DIDfarm into your platform.

Overview

The DIDfarm API is a REST API that returns JSON. All endpoints are served over HTTPS at https://didfarm.com/api/v1/. Authentication uses Bearer tokens (API keys). Rate limits are generous for partner accounts.

The API lets you automate the full number lifecycle: search inventory, purchase numbers, create SIP trunks, assign routing, query billing, and receive real-time events via webhooks.

Authentication

All API requests require a Bearer token in the Authorization header.

Generate an API Key

  1. Log in to didfarm.com/my-numbers
  2. Go to Account → API Keys
  3. Click Generate Key
  4. Copy the key immediately — it is shown only once
Authentication Header
Authorization: Bearer df_live_abc123def456...
Keep your API key secret. Do not commit it to version control, expose it in client-side code, or share it in plain text. Rotate keys immediately if you suspect a leak.

Error Responses

All errors return a consistent JSON structure:

Error Format
{
  "error": {
    "code": "insufficient_balance",
    "message": "Wallet balance too low for this purchase.",
    "status": 422
  }
}
Status Code Meaning
200Success
201Resource created
401Invalid or missing API key
403Forbidden (insufficient permissions)
404Resource not found
422Validation error (check error message)
429Rate limit exceeded
500Server error (retry with backoff)

Provision Numbers for Clients

Provisioning a number for a client involves three steps: search, purchase, and assign.

Search Available Numbers

GET /api/v1/numbers/search
curl "https://didfarm.com/api/v1/numbers/search?country=NL&type=local&city=Amsterdam" \
  -H "Authorization: Bearer $API_KEY"
Response
{
  "data": [
    {
      "number": "+31201234567",
      "country": "NL",
      "type": "local",
      "city": "Amsterdam",
      "monthly_rate": 150,
      "setup_fee": 0,
      "sms_enabled": false,
      "requires_regulatory": true
    }
  ],
  "meta": { "total": 48, "page": 1 }
}
Prices in cents: The monthly_rate and setup_fee fields are returned in EUR cents. Divide by 100 for display (e.g., 150 = EUR 1.50/month).

Purchase a Number

POST /api/v1/wallet/checkout
curl -X POST "https://didfarm.com/api/v1/wallet/checkout" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "number": "+31201234567",
        "country": "NL",
        "type": "local"
      }
    ]
  }'

The purchase is atomic: wallet debit, order creation, and provisioning happen in a single transaction. If any step fails, the wallet is not debited.

Assign to a Trunk

POST /api/v1/portal/did-routing
curl -X POST "https://didfarm.com/api/v1/portal/did-routing" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "did_number_id": 42,
    "sip_trunk_id": 7
  }'

Create Client SIP Trunks

Each client should have their own SIP trunk with isolated credentials.

POST /api/v1/portal/sip-trunks
curl -X POST "https://didfarm.com/api/v1/portal/sip-trunks" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Corp",
    "auth_type": "digest"
  }'
Response
{
  "data": {
    "uuid": "trk_a1b2c3d4",
    "name": "Acme Corp",
    "sip_server": "sip.didfarm.com",
    "username": "acme_xk9f2",
    "password": "Rn8kP2mQ...",
    "status": "provisioning"
  }
}
Save the password immediately. The password field is returned only in the creation response. Store it securely and share it with your client. You can regenerate credentials later, but this will disconnect the client's PBX.

List Trunks

GET /api/v1/portal/sip-trunks
curl "https://didfarm.com/api/v1/portal/sip-trunks" \
  -H "Authorization: Bearer $API_KEY"

Regenerate Credentials

POST /api/v1/portal/sip-trunks/{uuid}/regenerate-credentials
curl -X POST "https://didfarm.com/api/v1/portal/sip-trunks/trk_a1b2c3d4/regenerate-credentials" \
  -H "Authorization: Bearer $API_KEY"

Send Messages for Clients

If a number supports SMS, you can send outbound messages via the API:

POST /api/v1/messages/send
curl -X POST "https://didfarm.com/api/v1/messages/send" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "+31612345678",
    "to": "+31687654321",
    "body": "Your appointment is confirmed for tomorrow at 10:00."
  }'
SMS availability: Not all numbers support SMS. Check the sms_enabled field in the number search response. SMS rates are charged per message and deducted from your wallet.

Billing per Client

Use the transaction history API to calculate per-client costs:

GET /api/v1/wallet/transactions
curl "https://didfarm.com/api/v1/wallet/transactions?page=1" \
  -H "Authorization: Bearer $API_KEY"

Each transaction includes a reference_type and reference_id that links back to the order, number, or trunk. Use this to aggregate costs by client trunk and generate your own invoices.

Check Wallet Balance

GET /api/v1/wallet/balance
curl "https://didfarm.com/api/v1/wallet/balance" \
  -H "Authorization: Bearer $API_KEY"

# Response: { "balance": "142.50", "currency": "EUR" }

Webhooks

DIDfarm can send real-time HTTP POST notifications to your server when events occur. Configure your webhook URL in the portal under Account → Webhooks.

Event Description
number.activatedA number has been provisioned and is live
number.suspendedA number was suspended (e.g., renewal failed)
number.releasedA number was returned to the carrier pool
regulatory.approvedRegulatory documents were approved
regulatory.rejectedRegulatory documents were rejected
trunk.registeredA SIP trunk successfully registered
trunk.offlineA SIP trunk lost registration
message.receivedAn inbound SMS was received on a number
Webhook Payload Example
{
  "event": "number.activated",
  "timestamp": "2026-04-05T14:30:00Z",
  "data": {
    "number": "+31201234567",
    "country": "NL",
    "type": "local",
    "trunk_uuid": "trk_a1b2c3d4",
    "order_id": 1042
  }
}
Verify webhooks: Each webhook request includes an X-DIDfarm-Signature header. Validate the HMAC-SHA256 signature using your webhook secret to ensure the request is genuine.

Code Examples

Below is a complete Node.js example that provisions a number and creates a trunk for a new client.

Node.js — Full Client Onboarding
const API_KEY = process.env.DIDFARM_API_KEY;
const BASE = 'https://didfarm.com/api/v1';

async function api(method, path, body) {
  const res = await fetch(`${BASE}${path}`, {
    method,
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: body ? JSON.stringify(body) : undefined,
  });
  if (!res.ok) throw new Error(`API ${res.status}: ${await res.text()}`);
  return res.json();
}

async function onboardClient(clientName, country, type) {
  // 1. Search for an available number
  const search = await api('GET',
    `/numbers/search?country=${country}&type=${type}`);
  const number = search.data[0];
  console.log(`Found: ${number.number} at ${number.monthly_rate} cents/mo`);

  // 2. Purchase the number
  const order = await api('POST', '/wallet/checkout', {
    items: [{ number: number.number, country, type }],
  });
  console.log(`Order #${order.data.order_id} created`);

  // 3. Create a SIP trunk for the client
  const trunk = await api('POST', '/portal/sip-trunks', {
    name: clientName,
    auth_type: 'digest',
  });
  console.log(`Trunk: ${trunk.data.username} / ${trunk.data.password}`);

  // 4. Assign the number to the trunk
  await api('POST', '/portal/did-routing', {
    did_number_id: order.data.items[0].did_number_id,
    sip_trunk_id: trunk.data.id,
  });
  console.log(`${number.number} assigned to ${clientName}`);

  return { number: number.number, trunk: trunk.data };
}

// Usage
onboardClient('Acme Corp', 'NL', 'local')
  .then(result => console.log('Done:', result))
  .catch(err => console.error('Error:', err));

Frequently Asked Questions

What are the rate limits?

Partner accounts are allowed 60 requests per minute by default. If you need higher limits for bulk provisioning, contact the partnerships team to increase your quota.

Is there a sandbox environment?

A sandbox environment is on the roadmap. For now, test with low-cost numbers (e.g., US local numbers) on the live API. Refunds for test numbers can be arranged with support.

Can I use the API with Sanctum cookie auth instead of API keys?

Yes, if you are building a frontend that authenticates users via the DIDfarm login flow. Sanctum cookie auth works for browser-based SPA requests. For server-to-server integration, use API keys.

How do I handle regulatory requirements via API?

When a number requires regulatory documents, the checkout response includes a requires_regulatory: true flag. Use the POST /api/regulatory/submit endpoint to upload documents and submit for review. The regulatory.approved webhook fires when documents are approved.

What happens if my webhook endpoint is down?

DIDfarm retries webhook deliveries with exponential backoff for up to 24 hours. After that, the event is dropped. Monitor your webhook endpoint uptime to avoid missing events.

Start building with the API

Generate an API key and make your first request in minutes.

Get API Key →
© 2026 DIDfarm · didfarm.com
About Blog Partners Coverage API Docs Status Privacy Terms Cookies Help

We use essential cookies to make DIDfarm work. With your consent, we also use analytics cookies to improve our service. Cookie Policy