{
  "info": {
    "name": "Tecron Public API",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "description": "Generated from tecron-public-v1.yaml. Use X-Tecron-Key / X-Tecron-Secret only."
  },
  "item": [
    {
      "name": "Liveness check",
      "request": {
        "name": "Liveness check",
        "description": {
          "content": "Does not probe Mongo, Redis, or Graph. Rejects requests that carry an Origin header.",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "health"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": []
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": null
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Authenticated workspace identity",
      "request": {
        "name": "Authenticated workspace identity",
        "description": {},
        "url": {
          "path": [
            "account"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": []
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "List connected WhatsApp numbers",
      "request": {
        "name": "List connected WhatsApp numbers",
        "description": {},
        "url": {
          "path": [
            "channels"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": []
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Get one connected WhatsApp number",
      "request": {
        "name": "Get one connected WhatsApp number",
        "description": {},
        "url": {
          "path": [
            "channels",
            ":channelId"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": [
            {
              "disabled": false,
              "type": "any",
              "value": "<string>",
              "key": "channelId",
              "description": "(Required) "
            }
          ]
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "List approved templates",
      "request": {
        "name": "List approved templates",
        "description": {},
        "url": {
          "path": [
            "templates"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [
            {
              "disabled": false,
              "key": "channelId",
              "value": "<string>"
            },
            {
              "disabled": false,
              "key": "status",
              "value": "approved"
            }
          ],
          "variable": []
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Get one template",
      "request": {
        "name": "Get one template",
        "description": {},
        "url": {
          "path": [
            "templates",
            ":templateId"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": [
            {
              "disabled": false,
              "type": "any",
              "value": "<string>",
              "key": "templateId",
              "description": "(Required) "
            }
          ]
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "List public API messages",
      "request": {
        "name": "List public API messages",
        "description": {
          "content": "Cursor pagination only (no skip/offset). Returns this workspace's public_api messages (publicId set). Inbox/broadcast/flow rows are omitted. Other-tenant channelId returns 404 channel_not_found, not an empty page.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "messages"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [
            {
              "disabled": false,
              "key": "channelId",
              "value": "<string>"
            },
            {
              "disabled": false,
              "key": "status",
              "value": "<string>"
            },
            {
              "disabled": false,
              "key": "from",
              "value": "<dateTime>",
              "description": "Inclusive createdAt lower bound (ISO-8601)"
            },
            {
              "disabled": false,
              "key": "to",
              "value": "<dateTime>",
              "description": "Exclusive createdAt upper bound (ISO-8601)"
            },
            {
              "disabled": false,
              "key": "limit",
              "value": "25"
            },
            {
              "disabled": false,
              "key": "cursor",
              "value": "<string>",
              "description": "Opaque HMAC cursor from nextCursor"
            }
          ],
          "variable": []
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Accept a template send",
      "request": {
        "name": "Accept a template send",
        "description": {
          "content": "Always returns HTTP 202 with status queued. Test keys simulate delivery after accept so a subsequent GET may already show delivered. Live keys return 403 live_send_not_enabled while PUBLIC_API_LIVE_SEND is off, or 202 queued when the flag is on. GET may later show sending, sent, or failed. template.variables is scoped (header / body / buttons[].params), not a flat public variables map. Never exposes Graph send path or MM Lite.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "messages",
            "template"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": []
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "disabled": false,
            "key": "Idempotency-Key",
            "value": "<string>",
            "description": ""
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "POST",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        },
        "body": {
          "mode": "raw",
          "raw": "{\n  \"callbackUrl\": \"<uri>\",\n  \"channelId\": \"<string>\",\n  \"clientMessageId\": \"<string>\",\n  \"template\": {\n    \"header\": {\n      \"type\": \"<string>\",\n      \"url\": \"<string>\"\n    },\n    \"id\": \"<string>\",\n    \"language\": \"<string>\",\n    \"name\": \"<string>\",\n    \"variables\": {\n      \"body\": {\n        \"key_0\": \"<string>\"\n      },\n      \"buttons\": [\n        {\n          \"index\": \"<integer>\",\n          \"params\": {\n            \"key_0\": \"<string>\"\n          }\n        }\n      ],\n      \"header\": {\n        \"key_0\": \"<string>\"\n      }\n    }\n  },\n  \"to\": \"<string>\"\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Accept a session (customer-care window) send",
      "request": {
        "name": "Accept a session (customer-care window) send",
        "description": {
          "content": "Always returns HTTP 202 with status queued. Allowed only while the 24-hour customer-care window is open (Conversation.lastIncomingMessageAt). Closed or missing inbound returns 400 outside_24h_window with no message row. Test keys still require an open window; 202 body is still queued. type defaults to text. image, video, audio, and document require an HTTPS url that is HEAD'd at accept (SSRF + size/MIME); Graph send uses a media id from cache, never link. location and interactive (reply buttons or list) are also accepted. Optional replyTo is a msg_ id in this conversation; a queued target returns 409 reply_target_not_sent with Retry-After 2 (poll GET until sent). expiresAt is a 30-minute queue TTL capped by remaining window. Never phoneNumberId.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "messages",
            "session"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": []
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "disabled": false,
            "key": "Idempotency-Key",
            "value": "<string>",
            "description": ""
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "POST",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        },
        "body": {
          "mode": "raw",
          "raw": "{\n  \"callbackUrl\": \"<uri>\",\n  \"channelId\": \"<string>\",\n  \"clientMessageId\": \"<string>\",\n  \"replyTo\": \"<string>\",\n  \"text\": {\n    \"body\": \"<string>\",\n    \"previewUrl\": false\n  },\n  \"to\": \"<string>\",\n  \"type\": \"<string>\"\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Get one accepted public API message",
      "request": {
        "name": "Get one accepted public API message",
        "description": {
          "content": "Lookup is by company + publicId (msg_…). Inbox rows without publicId return message_not_found even if the ObjectId is encoded as msg_. Status may be queued, sending, sent, delivered, read, failed, or cancelled. Failed rows may include mapped errorCode plus error.meta { code, title }. Session (free-form) rows include kind session and session.type (text, image, video, audio, document, location, or interactive); template rows omit kind. Never phoneNumberId, media URL, or Graph send path.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "messages",
            ":messageId"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": [
            {
              "disabled": false,
              "type": "any",
              "value": "<string>",
              "key": "messageId",
              "description": "(Required) "
            }
          ]
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "List contacts",
      "request": {
        "name": "List contacts",
        "description": {
          "content": "Cursor pagination only (no skip/offset). Active contacts for this workspace. Optional exact phone (E.164) and tag filters. Invalid phone format returns invalid_query; a valid unknown phone returns an empty data array. Scope contacts:read (write-only keys get insufficient_scope).\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "contacts"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [
            {
              "disabled": false,
              "key": "phone",
              "value": "<string>",
              "description": "Exact E.164 filter (+ required). List returns 0–1 rows."
            },
            {
              "disabled": false,
              "key": "tag",
              "value": "<string>",
              "description": "Exact tag match"
            },
            {
              "disabled": false,
              "key": "limit",
              "value": "25"
            },
            {
              "disabled": false,
              "key": "cursor",
              "value": "<string>",
              "description": "Opaque HMAC cursor from nextCursor"
            }
          ],
          "variable": []
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Create or update a contact by E.164",
      "request": {
        "name": "Create or update a contact by E.164",
        "description": {
          "content": "Upsert on company + phoneNumber. Live API keys only — test keys return 403 test_key_cannot_write_contacts (contacts are shared with the dashboard; writes require a live API key). Returns 201 on insert with Location /v1/contacts/{id}, or 200 on update/restore. Tags default to additive ($addToSet); set replaceTags true to replace the whole array (including [] to clear). Contact.tags are used for Leads filters, inbox, flows, and dashboard tag audiences. notes replaces Contact.notes (Contacts form / lead contact snapshot only) — it does not change conversation thread notes (ConversationNote). Create requires name. Scope contacts:write. No Idempotency-Key; natural key is E.164.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "contacts"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": []
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "POST",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        },
        "body": {
          "mode": "raw",
          "raw": "{\n  \"email\": \"<email>\",\n  \"name\": \"<string>\",\n  \"notes\": \"<string>\",\n  \"phoneNumber\": \"<string>\",\n  \"replaceTags\": false,\n  \"tags\": [\n    \"<string>\"\n  ]\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Get one contact by E.164",
      "request": {
        "name": "Get one contact by E.164",
        "description": {
          "content": "Primary lookup. Path e164 must be URL-encoded E.164 including +. Invalid format → 400 invalid_query. Miss, inactive, or other tenant → 404 contact_not_found. Scope contacts:read.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "contacts",
            "by-phone",
            ":e164"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": [
            {
              "disabled": false,
              "type": "any",
              "value": "<string>",
              "key": "e164",
              "description": "(Required) E.164 including + (URL-encode, e.g. %2B9198…)"
            }
          ]
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Get one contact by id",
      "request": {
        "name": "Get one contact by id",
        "description": {
          "content": "Opaque ct_ id. Bad format, unknown, other tenant, or inactive → 404 contact_not_found (never 403). Scope contacts:read.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "contacts",
            ":contactId"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": [
            {
              "disabled": false,
              "type": "any",
              "value": "<string>",
              "key": "contactId",
              "description": "(Required) "
            }
          ]
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Update a contact",
      "request": {
        "name": "Update a contact",
        "description": {
          "content": "Live API keys only — test keys return 403 test_key_cannot_write_contacts. Same tag and notes rules as POST update. phoneNumber in the body → 400 phone_immutable. Inactive → 404. Scope contacts:write.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "contacts",
            ":contactId"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": [
            {
              "disabled": false,
              "type": "any",
              "value": "<string>",
              "key": "contactId",
              "description": "(Required) "
            }
          ]
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "PATCH",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        },
        "body": {
          "mode": "raw",
          "raw": "{\n  \"email\": \"<email>\",\n  \"name\": \"<string>\",\n  \"notes\": \"<string>\",\n  \"replaceTags\": false,\n  \"tags\": [\n    \"<string>\"\n  ]\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Soft-delete a contact",
      "request": {
        "name": "Soft-delete a contact",
        "description": {
          "content": "Sets isActive false. Live API keys only — test keys return 403 test_key_cannot_write_contacts. Already inactive or other tenant → 404. Does not hard-delete or remove messages/conversations. Scope contacts:write.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "contacts",
            ":contactId"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": [
            {
              "disabled": false,
              "type": "any",
              "value": "<string>",
              "key": "contactId",
              "description": "(Required) "
            }
          ]
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "DELETE",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "List public API broadcasts",
      "request": {
        "name": "List public API broadcasts",
        "description": {
          "content": "Cursor list of campaigns with source public_api only. Dashboard campaigns are omitted. Scope messages:read or messages:send.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "broadcasts"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [
            {
              "disabled": false,
              "key": "status",
              "value": "<string>"
            },
            {
              "disabled": false,
              "key": "limit",
              "value": "25"
            },
            {
              "disabled": false,
              "key": "cursor",
              "value": "<string>"
            }
          ],
          "variable": []
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Accept a template broadcast",
      "request": {
        "name": "Accept a template broadcast",
        "description": {
          "content": "Explicit to[] (1–1000 unique E.164) + one approved template. Returns 202 queued with bc_ id. Live keys only — test keys return 403 test_key_cannot_broadcast. Uses broadcast-start-prep / broadcast-send queues (not N public-api-send jobs). Daily cap INCRBY N. Same template variables for every recipient. Idempotency-Key supported.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "broadcasts"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": []
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "disabled": false,
            "key": "Idempotency-Key",
            "value": "<string>",
            "description": ""
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "POST",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        },
        "body": {
          "mode": "raw",
          "raw": "{\n  \"channelId\": \"<string>\",\n  \"name\": \"<string>\",\n  \"template\": {\n    \"key_0\": \"<string>\"\n  },\n  \"to\": [\n    \"<string>\"\n  ]\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Get one public API broadcast",
      "request": {
        "name": "Get one public API broadcast",
        "description": {
          "content": "Isolation 404 broadcast_not_found for other tenant or dashboard rows. Exposes skipped separately from failed.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "broadcasts",
            ":broadcastId"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": [
            {
              "disabled": false,
              "type": "any",
              "value": "<string>",
              "key": "broadcastId",
              "description": "(Required) "
            }
          ]
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "List broadcast recipients",
      "request": {
        "name": "List broadcast recipients",
        "description": {
          "content": "Cursor on recipient _id. Partial failure visibility.",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "broadcasts",
            ":broadcastId",
            "recipients"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [
            {
              "disabled": false,
              "key": "status",
              "value": "<string>"
            },
            {
              "disabled": false,
              "key": "limit",
              "value": "25"
            },
            {
              "disabled": false,
              "key": "cursor",
              "value": "<string>"
            }
          ],
          "variable": [
            {
              "disabled": false,
              "type": "any",
              "value": "<string>",
              "key": "broadcastId",
              "description": "(Required) "
            }
          ]
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "GET",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Cancel a public API broadcast",
      "request": {
        "name": "Cancel a public API broadcast",
        "description": {
          "content": "Sets Redis cancel flag and marks pending/queued/retrying recipients cancelled. Worker checks cancel before every Graph call. Live keys only.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "broadcasts",
            ":broadcastId",
            "cancel"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": [
            {
              "disabled": false,
              "type": "any",
              "value": "<string>",
              "key": "broadcastId",
              "description": "(Required) "
            }
          ]
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "POST",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Retry failed recipients",
      "request": {
        "name": "Retry failed recipients",
        "description": {
          "content": "Only failed rows with publicRetryCount less than 3. INCRBY R daily cap. 429 if remaining less than R. 409 retry_exhausted if R is 0. Live keys only.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "broadcasts",
            ":broadcastId",
            "retry-failed"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": [
            {
              "disabled": false,
              "type": "any",
              "value": "<string>",
              "key": "broadcastId",
              "description": "(Required) "
            }
          ]
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "POST",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    },
    {
      "name": "Re-enqueue start-prep",
      "request": {
        "name": "Re-enqueue start-prep",
        "description": {
          "content": "For failed or stuck queued public campaigns. Does not INCR daily caps (rows already reserved). Live keys only.\n",
          "type": "text/plain"
        },
        "url": {
          "path": [
            "broadcasts",
            ":broadcastId",
            "retry-prep"
          ],
          "host": [
            "{{baseUrl}}"
          ],
          "query": [],
          "variable": [
            {
              "disabled": false,
              "type": "any",
              "value": "<string>",
              "key": "broadcastId",
              "description": "(Required) "
            }
          ]
        },
        "header": [
          {
            "key": "X-Tecron-Key",
            "value": "{{tecronKey}}",
            "type": "text"
          },
          {
            "key": "X-Tecron-Secret",
            "value": "{{tecronSecret}}",
            "type": "text"
          },
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "method": "POST",
        "auth": {
          "type": "apikey",
          "apikey": [
            {
              "key": "key",
              "value": "X-Tecron-Key"
            },
            {
              "key": "value",
              "value": "{{apiKey}}"
            },
            {
              "key": "in",
              "value": "header"
            }
          ]
        }
      },
      "response": [],
      "event": [],
      "protocolProfileBehavior": {
        "disableBodyPruning": true
      }
    }
  ],
  "auth": {
    "type": "apikey",
    "apikey": [
      {
        "key": "key",
        "value": "X-Tecron-Key",
        "type": "string"
      },
      {
        "key": "value",
        "value": "{{tecronKey}}",
        "type": "string"
      },
      {
        "key": "in",
        "value": "header",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://api.tecron.in/v1"
    },
    {
      "key": "tecronKey",
      "value": "tk_live_YOUR_KEY_ID"
    },
    {
      "key": "tecronSecret",
      "value": "YOUR_API_SECRET"
    }
  ]
}
