{"openapi":"3.1.0","info":{"title":"MBOS Communications Portal API","version":"2.5.0","description":"Send SMS surveys, load reward stock, and read delivery, answer and spend data. Every key is bound to one workspace: no request can ever reach another workspace's data.","contact":{"name":"MBOS Information Officer","email":"privacy@mbos.co.za"}},"servers":[{"url":"https://www.methodbox.co.za"}],"components":{"securitySchemes":{"bearerApiKey":{"type":"http","scheme":"bearer","description":"A workspace API key created in Settings → Developer API. Send as Authorization: Bearer <key> (or x-api-key)."}}},"security":[{"bearerApiKey":[]}],"paths":{"/api/public/v1/campaigns":{"get":{"summary":"List the campaigns in the workspace the key belongs to.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"Filter by campaign status, e.g. draft, active, closed.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"How many to return (max 200, default 50).","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":"{ \"data\": [ { \"id\": \"…\", \"name\": \"August NPS\", \"status\": \"active\", \"reward_cap\": 500 } ], \"count\": 1 }"}}},"401":{"description":"Missing or invalid API key"},"403":{"description":"The key does not carry the permission this endpoint needs"},"404":{"description":"Not found in the workspace the key belongs to"},"409":{"description":"Blocked by a business rule, e.g. not enough reward codes"}}}},"/api/public/v1/campaigns/{id}":{"get":{"summary":"One campaign with live totals for people, messages and rewards.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":"{ \"data\": { \"id\": \"…\", \"totals\": { \"people\": 1200, \"completed\": 431, \"rewards_issued\": 431 } } }"}}},"401":{"description":"Missing or invalid API key"},"403":{"description":"The key does not carry the permission this endpoint needs"},"404":{"description":"Not found in the workspace the key belongs to"},"409":{"description":"Blocked by a business rule, e.g. not enough reward codes"}}}},"/api/public/v1/campaigns/{id}/activate":{"post":{"summary":"Take a campaign live. Refused with 409 when there are not enough reward codes for the promise you made.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":"{ \"data\": { \"id\": \"…\", \"status\": \"active\", \"warning\": null } }"}}},"401":{"description":"Missing or invalid API key"},"403":{"description":"The key does not carry the permission this endpoint needs"},"404":{"description":"Not found in the workspace the key belongs to"},"409":{"description":"Blocked by a business rule, e.g. not enough reward codes"}}}},"/api/public/v1/respondents":{"get":{"summary":"List the people on a campaign. Mobile numbers are masked unless the key has write permission.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"campaign_id","in":"query","required":false,"description":"Limit to one campaign.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"How many to return (max 500, default 100).","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":"{ \"data\": [ { \"id\": \"…\", \"name\": \"Thabo\", \"phone\": \"+27•••••7866\", \"status\": \"sent\" } ], \"numbers_masked\": true }"}}},"401":{"description":"Missing or invalid API key"},"403":{"description":"The key does not carry the permission this endpoint needs"},"404":{"description":"Not found in the workspace the key belongs to"},"409":{"description":"Blocked by a business rule, e.g. not enough reward codes"}}},"post":{"summary":"Add people to a campaign in bulk (up to 5 000 per call). Numbers are normalised to South African format and duplicates are skipped.","security":[{"bearerApiKey":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"},"example":"{ \"campaign_id\": \"…\", \"people\": [ { \"name\": \"Thabo\", \"phone\": \"083 776 7866\" } ] }"}}},"responses":{"200":{"description":"Success","content":{"application/json":{"example":"{ \"data\": { \"added\": 1, \"rejected\": [] } }"}}},"401":{"description":"Missing or invalid API key"},"403":{"description":"The key does not carry the permission this endpoint needs"},"404":{"description":"Not found in the workspace the key belongs to"},"409":{"description":"Blocked by a business rule, e.g. not enough reward codes"}}}},"/api/public/v1/rewards":{"get":{"summary":"List reward records and whether each one is still available, allocated or issued.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"campaign_id","in":"query","required":false,"description":"Limit to one campaign.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":"{ \"data\": [ { \"id\": \"…\", \"code\": \"VCHR-1\", \"status\": \"available\" } ], \"count\": 1 }"}}},"401":{"description":"Missing or invalid API key"},"403":{"description":"The key does not carry the permission this endpoint needs"},"404":{"description":"Not found in the workspace the key belongs to"},"409":{"description":"Blocked by a business rule, e.g. not enough reward codes"}}},"post":{"summary":"Load reward codes or links in bulk (up to 5 000 per call).","security":[{"bearerApiKey":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"},"example":"{ \"campaign_id\": \"…\", \"rewards\": [ { \"code\": \"VCHR-1\", \"value\": \"R50\", \"type\": \"voucher_code\" } ] }"}}},"responses":{"200":{"description":"Success","content":{"application/json":{"example":"{ \"data\": { \"added\": 1, \"rejected\": [] } }"}}},"401":{"description":"Missing or invalid API key"},"403":{"description":"The key does not carry the permission this endpoint needs"},"404":{"description":"Not found in the workspace the key belongs to"},"409":{"description":"Blocked by a business rule, e.g. not enough reward codes"}}}},"/api/public/v1/messages":{"get":{"summary":"Delivery status and cost of every SMS, for reconciliation.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"campaign_id","in":"query","required":false,"description":"Limit to one campaign.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Filter by delivery status, e.g. delivered, failed.","schema":{"type":"string"}},{"name":"since","in":"query","required":false,"description":"ISO timestamp, only messages created after this.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":"{ \"data\": [ { \"id\": \"…\", \"status\": \"delivered\", \"provider_charge\": 0.21, \"provider_currency\": \"ZAR\" } ] }"}}},"401":{"description":"Missing or invalid API key"},"403":{"description":"The key does not carry the permission this endpoint needs"},"404":{"description":"Not found in the workspace the key belongs to"},"409":{"description":"Blocked by a business rule, e.g. not enough reward codes"}}}},"/api/public/v1/reports/{campaignId}":{"get":{"summary":"Reporting totals for a campaign: people, delivery, answers, rewards and spend.","security":[{"bearerApiKey":[]}],"parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":"{ \"data\": { \"people_total\": 1200, \"responses_total\": 431, \"estimated_spend\": 264.5, \"currency\": \"ZAR\" } }"}}},"401":{"description":"Missing or invalid API key"},"403":{"description":"The key does not carry the permission this endpoint needs"},"404":{"description":"Not found in the workspace the key belongs to"},"409":{"description":"Blocked by a business rule, e.g. not enough reward codes"}}}},"/api/public/webhooks/sms-status":{"post":{"summary":"Delivery receipts from an SMS network. Authenticated with the workspace delivery key header, not an API key.","security":[{"bearerApiKey":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"example":"{ \"ok\": true, \"updated\": 1 }"}}},"401":{"description":"Missing or invalid API key"},"403":{"description":"The key does not carry the permission this endpoint needs"},"404":{"description":"Not found in the workspace the key belongs to"},"409":{"description":"Blocked by a business rule, e.g. not enough reward codes"}}}},"/api/public/webhooks/sms-reply":{"post":{"summary":"Inbound replies from an SMS network. Uses the same delivery key header.","security":[{"bearerApiKey":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"example":"{ \"ok\": true }"}}},"401":{"description":"Missing or invalid API key"},"403":{"description":"The key does not carry the permission this endpoint needs"},"404":{"description":"Not found in the workspace the key belongs to"},"409":{"description":"Blocked by a business rule, e.g. not enough reward codes"}}}}}}