{
  "info": {
    "name": "SENDPK Voice Call API",
    "_postman_id": "5c3e8a41-7d2b-4f6e-9a10-2b7c4d5e6f81",
    "description": "Call a Pakistani mobile number and play one of your APPROVED voice recordings, optionally collecting key presses (DTMF).\n\nSetup\n1. Open the collection Variables tab.\n2. Put your SENDPK API key in `api_key`.\n3. Put your own mobile number in `phone_number`.\n4. Run \"1. Check my key\" (free) and copy the id of an approved recording into `template_id`.\n5. Change `idempotency_key` to a new value for every NEW call.\n6. Run \"3. Place a call\" - it COSTS MONEY and saves the call id into `call_id`.\n7. Run \"5. Call status\".\n\nDocs: https://sendpk.com/voice_call_api.php\nYour API key is secret. Never share this collection after filling it in.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "variable": [
    {
      "key": "base_url",
      "value": "https://sendpk.com/apps/phone_calls",
      "type": "string"
    },
    {
      "key": "api_key",
      "value": "YOUR_API_KEY",
      "type": "string"
    },
    {
      "key": "phone_number",
      "value": "+923001234567",
      "type": "string"
    },
    {
      "key": "template_id",
      "value": "3301118",
      "type": "string"
    },
    {
      "key": "idempotency_key",
      "value": "postman-test-call-1",
      "type": "string"
    },
    {
      "key": "call_id",
      "value": "",
      "type": "string"
    },
    {
      "key": "webhook_url",
      "value": "https://example.com/webhooks/voice-call",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "1. Check my key (list my recordings)",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Authorization",
            "value": "{{api_key}}"
          }
        ],
        "url": {
          "raw": "{{base_url}}/templates.php",
          "host": [
            "{{base_url}}"
          ],
          "path": [
            "templates.php"
          ]
        },
        "description": "Free. Places no call.\n\n200 = your API key, IP whitelist and account are all fine; data.templates lists your recordings.\n401 AUTH_MISSING / AUTH_INVALID = the key is missing or wrong.\n403 IP_NOT_ALLOWED = whitelist details.ip in Profile.\n403 SERVICE_DISABLED = ask SENDPK to switch voice calls on."
      },
      "response": [],
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "var body = pm.response.json();",
              "pm.test('API key works', function () { pm.expect(pm.response.code, body.error ? body.error.code : '').to.eql(200); });",
              "if (body.success) { (body.data.templates || []).forEach(function (t) { console.log(t.id, t.status, t.title, t.duration + ' s'); }); }"
            ]
          }
        }
      ]
    },
    {
      "name": "2. One recording",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Authorization",
            "value": "{{api_key}}"
          }
        ],
        "url": {
          "raw": "{{base_url}}/templates.php?id={{template_id}}",
          "host": [
            "{{base_url}}"
          ],
          "path": [
            "templates.php"
          ],
          "query": [
            {
              "key": "id",
              "value": "{{template_id}}"
            }
          ]
        },
        "description": "One recording by id. 404 TEMPLATE_NOT_FOUND = not on your account."
      },
      "response": []
    },
    {
      "name": "3. Place a call",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Authorization",
            "value": "{{api_key}}"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Idempotency-Key",
            "value": "{{idempotency_key}}"
          }
        ],
        "url": {
          "raw": "{{base_url}}/call.php",
          "host": [
            "{{base_url}}"
          ],
          "path": [
            "call.php"
          ]
        },
        "description": "COSTS MONEY: the full price (30-second pulses of the recording x your price per pulse) is taken now and given back if nobody answers (default).\n\nSending it again with the SAME Idempotency-Key and body returns the same call (reused: true), no second call. Change idempotency_key for a new call.",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"number\": \"{{phone_number}}\",\n  \"template_id\": {{template_id}}\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "response": [],
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "var body = pm.response.json();",
              "if (body.success && body.data && body.data.id) {",
              "    pm.collectionVariables.set('call_id', body.data.id);",
              "    console.log('Saved call_id', body.data.id, 'status', body.data.status);",
              "} else if (body.error) {",
              "    console.log('Not placed:', pm.response.code, body.error.code, body.error.message);",
              "}"
            ]
          }
        }
      ]
    },
    {
      "name": "4. Place a call with key presses",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Authorization",
            "value": "{{api_key}}"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Idempotency-Key",
            "value": "{{idempotency_key}}"
          }
        ],
        "url": {
          "raw": "{{base_url}}/call.php",
          "host": [
            "{{base_url}}"
          ],
          "path": [
            "call.php"
          ]
        },
        "description": "COSTS MONEY. Plays the recording, then waits 10 seconds for 1 key; only 1 or 2 count as valid. Result in dtmf.digits / dtmf.valid. Uses a different body, so give it its own idempotency_key.",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"number\": \"{{phone_number}}\",\n  \"template_id\": {{template_id}},\n  \"dtmf\": {\n    \"max_digits\": 1,\n    \"timeout\": 10,\n    \"valid_digits\": \"12\"\n  },\n  \"notification_callback\": \"{{webhook_url}}\"\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "response": [],
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "var body = pm.response.json();",
              "if (body.success && body.data && body.data.id) {",
              "    pm.collectionVariables.set('call_id', body.data.id);",
              "    console.log('Saved call_id', body.data.id, 'status', body.data.status);",
              "} else if (body.error) {",
              "    console.log('Not placed:', pm.response.code, body.error.code, body.error.message);",
              "}"
            ]
          }
        }
      ]
    },
    {
      "name": "5. Call status",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Authorization",
            "value": "{{api_key}}"
          }
        ],
        "url": {
          "raw": "{{base_url}}/status.php?id={{call_id}}",
          "host": [
            "{{base_url}}"
          ],
          "path": [
            "status.php"
          ],
          "query": [
            {
              "key": "id",
              "value": "{{call_id}}"
            }
          ]
        },
        "description": "Free. Current state of the call saved in call_id: status, outcome, keys pressed, times, charge and webhook delivery."
      },
      "response": []
    }
  ]
}
