openapi: 3.0.3 info: title: MAAC Go Broadcast API version: 1.0.0 description: "MAAC Go — Taiwan-first self-serve SMS platform. Send transactional (OTP /\norder / reminder) and broadcast SMS with NCC compliance, MAAC delivery\nbackend, and real-time DLR webhooks.\n\n- Base URL: `https://sms.cresclab.com/api`\n- Auth: `Authorization: Bearer `\n- New accounts receive NT$50 trial credit on signup, enough to send real test SMS immediately.\n- API keys are scoped and wallet-backed; sending debits the account balance unless your deployment uses a mock SMS/payment adapter.\n- All phone numbers use E.164 (`+886912345678`). 09xxxxxxxx is also accepted.\n- Cost: NT$0.78 per SMS segment (Chinese: 70 chars/segment · English: 160/segment).\n- Rate-limit errors return `429 rate_limited` with limit/used details and retry guidance when available.\n- Delivery confirmations arrive asynchronously via webhook (`sms.delivered`\n / `sms.failed`); poll `GET /sms/{id}` as a fallback.\n- MCP clients (Claude / Cursor / Windsurf) can use this spec directly, or\n connect via `POST /api/mcp` (JSON-RPC 2.0) with the same bearer key.\n" contact: name: MAAC Go Support email: info@cresclab.com url: https://sms.cresclab.com license: name: Commercial url: https://sms.cresclab.com/terms.html servers: - url: https://sms.cresclab.com/api description: Production security: - bearerAuth: [] tags: - name: Broadcast description: Bulk (1-to-many) SMS. Small batches dispatch inline; >30 recipients queue asynchronously. paths: /broadcast: post: tags: - Broadcast summary: Create a broadcast (1-to-many) description: '≤ 30 recipients dispatch inline and return 200 with `delivered` / `failed` counts. \> 30 recipients queue async and return 202 with `status: "queued"`; cron dispatches in batches of 40 every 5 min; DLR webhooks flip individual messages. Schedule for later by passing `scheduled_at` (ISO 8601); funds reserve immediately, actual charge happens at send time. ' operationId: createBroadcast requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BroadcastCreateRequest' responses: '200': description: Sent inline (small broadcast) content: application/json: schema: $ref: '#/components/schemas/BroadcastSentResponse' '202': description: Queued for async dispatch (large broadcast) content: application/json: schema: $ref: '#/components/schemas/BroadcastQueuedResponse' '400': description: recipients_required / invalid_phones / ncc_blocked / too_many_recipients '402': description: insufficient_balance '429': description: rate_limited get: tags: - Broadcast summary: List broadcasts with per-broadcast delivery stats operationId: listBroadcasts responses: '200': description: OK content: application/json: schema: type: object properties: ok: type: boolean broadcasts: type: array items: $ref: '#/components/schemas/BroadcastSummary' components: schemas: BroadcastQueuedResponse: type: object properties: ok: type: boolean broadcast_id: type: string status: type: string enum: - queued recipient_count: type: integer cost_cents: type: integer dispatch: type: string enum: - async BroadcastCreateRequest: type: object required: - body - recipients properties: name: type: string description: Internal label for the campaign body: type: string description: Same NCC rules as /sms/send recipients: type: array items: type: string description: E.164 or 09xxxxxxxx minItems: 1 maxItems: 10000 scheduled_at: type: string format: date-time description: ISO 8601. Omit to send immediately. from: type: string team: type: string description: Cost-attribution team for the whole broadcast (e.g. `電商`). Overrides the API key's bound team; an unknown name is auto-created. example: 電商 BroadcastSentResponse: type: object properties: ok: type: boolean broadcast_id: type: string status: type: string enum: - sent recipient_count: type: integer delivered: type: integer description: Accepted by carrier — final status via webhook failed: type: integer cost_cents: type: integer refund_cents: type: integer balance_cents: type: integer team: type: string nullable: true description: Resolved cost-attribution team (null = 未分類). team_created: type: boolean description: True if this broadcast auto-created the team. BroadcastSummary: type: object properties: id: type: string name: type: string recipient_count: type: integer cost_cents: type: integer status: type: string enum: - scheduled - sending - sent - failed delivered_count: type: integer failed_count: type: integer sent_count: type: integer created_at: type: string format: date-time scheduled_at: type: string format: date-time nullable: true finished_at: type: string format: date-time nullable: true securitySchemes: bearerAuth: type: http scheme: bearer description: '`Authorization: Bearer `. Production keys start with `sk_live_`, test keys with `sk_test_` for environment separation. Sending still follows the account wallet and deployment adapter settings. '