# **ContextSMS Webex Bot API Integration Guide** # **Overview** The ContextSMS Webex Bot API lets you connect phone numbers with Webex messaging. When people send SMS/MMS to a phone number, messages appear in Webex. When a Webex team replies, the reply is forwarded as an SMS/MMS to the customer. ## **Who Uses This API** * **Customers:** Companies that want Webex teams to receive and send text messages. * **CSPs (Communication Service Providers):** Messaging providers who manage phone numbers and integrations for their business customers. ## **Key Features** * **Enterprise Management:** Create and manage customer organizations (enterprises). * **Phone Number Mapping:** Map phone numbers to Webex bot identities. * **Authentication:** JWT Bearer tokens and refresh flow. * **Webhooks:** Real-time inbound message event delivery. * **Environments:** Distinct development and production environments. # **Quick Integration Flow** 1. **Authenticate** → call `/auth/login` to obtain `accessToken` + `refreshToken`. 2. **Create Enterprise** → `POST /enterprise/{cspId}` to register the customer organization. 3. **Add Mapping** → `POST /mapping/add/{enterpriseId}` to link a phone number to a Webex bot. 4. **Receive Events** → implement a webhook endpoint to receive inbound message events. 5. **Send Messages** → call API endpoints or let the system forward messages from Webex to SMS. # **Base URLs** Use these hosts consistently in examples and your client implementations. Replace `{api_base}` with the chosen environment. * **Production API Base:** `https://context-webex.sabrhub.com/api/v1` * **Development API Base:** `https://webex-dev-frontend.sabrhub.com/api/v1` * **Authentication (Auth Service):** `https://usermanagement.sabrhub.com/v1` > **Tip:** Use server variables in generated SDKs or documentation tooling so you only change one place when switching environments. # **Authentication** All protected endpoints require a valid Bearer token in the `Authorization` header. ``` Authorization: Bearer ``` ## **Auth Flow (Primary)** 1. **Login** — exchange username/password for `accessToken` (JWT) and `refreshToken`. 2. **Refresh** — call the refresh endpoint to exchange `refreshToken` for a new `accessToken`. ### **POST /auth/login** **URL (Auth service):** `https://usermanagement.sabrhub.com/v1/auth/login` **Request** ```json { "username": "your-email@company.com", "password": "your-password" } ``` **Success Response (200)** ```json { "username": "your-email@company.com", "accessToken": "eyJhbGciOi...", "refreshToken": "eyJhbGciOi...", "expirationTimeInUTC": "2025-10-14T12:34:56Z", "roles": ["CSP_ADMIN"], "tenantId": "tenant123", "services": ["context-webex"] } ``` **cURL example** ```bash curl -X POST "https://usermanagement.sabrhub.com/v1/auth/login" \ -H "Content-Type: application/json" \ -d '{ "username": "your-email@company.com", "password": "your-password" }' ``` ### **POST /auth/getaccesstoken** **URL (Auth service):** `https://usermanagement.sabrhub.com/v1/auth/getaccesstoken` **Request** ```json { "username": "your-email@company.com", "refreshToken": "" } ``` **Success Response (200)** same schema as `/auth/login`. # **Common Headers** * `Authorization: Bearer ` (required for protected endpoints) * `Content-Type: application/json` * `Accept: application/json` # Schemas Use these field names consistently across endpoints and examples. * **Enterprise** * `enterpriseId` (string) * `name` (string) * `contact` (string) * `phoneNumber` (string, E.164) * `email` (string) * `defaultMmsSelection` (boolean) * `webexSettings` (object | null) * `numberToMessageAppMaps` (array | null) * `createdDate` (integer, epoch ms) * `updateDate` (integer, epoch ms) * **Number Mapping** * `numberToMessageAppMapId` (string) * `messagingAppId` (string) — e.g., the Webex bot ID * `phoneNumber` (string) — E.164 * `messagingAppType` (string) — e.g., `Webex` * `mmsEnabled` (boolean) * **AuthResponse** * `accessToken` (string) * `refreshToken` (string) * `expirationTimeInUTC` (date-time) * **ErrorResponse** * `error` (string) * `code` (string | integer) optional error code * `details` (object | null) optional additional info # **API Endpoints** > All endpoints shown against the canonical API base: `https://context-webex.sabrhub.com/api/v1` (swap with dev base as needed). ## **Authentication** ### **POST /auth/login** (Defined earlier auth service host `https://usermanagement.sabrhub.com/v1`) ### **POST /auth/getaccesstoken** (Defined earlier auth service host `https://usermanagement.sabrhub.com/v1`) ## **Enterprise Management** ### **POST /enterprise/{cspId}** Create Enterprise **URL:** `POST https://context-webex.sabrhub.com/api/v1/enterprise/{cspId}` **Path parameter** * `cspId` CSP identifier (e.g., `CSP001`) **Request body** ```json { "name": "ABC Marketing Company", "contact": "Sarah Johnson", "phoneNumber": "+15551234567", "email": "sarah@abcmarketing.com", "defaultMmsSelection": true } ``` **Success Response (201 Created)** ```json { "enterpriseId": "E0000123", "name": "ABC Marketing Company", "contact": "Sarah Johnson", "phoneNumber": "+15551234567", "email": "sarah@abcmarketing.com", "deleted": false, "createdDate": 1698446777442, "updateDate": 1698446777443, "webexSettings": null, "numberToMessageAppMaps": null, "defaultMmsSelection": true } ``` **cURL** ```bash curl -X POST "https://context-webex.sabrhub.com/api/v1/enterprise/CSP001" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "ABC Marketing Company", "contact": "Sarah Johnson", "phoneNumber": "+15551234567", "email": "sarah@abcmarketing.com", "defaultMmsSelection": true }' ``` ### **GET /enterprise/getenterprise/{enterpriseId}** Get Enterprise **URL:** `GET https://context-webex.sabrhub.com/api/v1/enterprise/getenterprise/{enterpriseId}` **Success (200)** returns the Enterprise object shown above. **cURL** ```bash curl -X GET "https://context-webex.sabrhub.com/api/v1/enterprise/getenterprise/E0000123" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ### **DELETE /enterprise/deleteenterprise/{enterpriseId}** Delete Enterprise **URL:** `DELETE https://context-webex.sabrhub.com/api/v1/enterprise/deleteenterprise/{enterpriseId}` **Success (204 No Content)** no body returned. If your API returns a message object, treat `200` as accepted but prefer `204`. **cURL** ```bash curl -X DELETE "https://context-webex.sabrhub.com/api/v1/enterprise/deleteenterprise/E0000123" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ## **Mapping Management** > ** Mapping payload fields:** `messagingAppId`, `phoneNumber`, `messagingAppType`, and `mmsEnabled` (optional). ### **POST /mapping/add/{enterpriseId}** Create Number Mapping **URL:** `POST https://context-webex.sabrhub.com/api/v1/mapping/add/{enterpriseId}` **Request body** ```json { "messagingAppId": "webex-bot-12345", "phoneNumber": "+15551234567", "messagingAppType": "Webex", "mmsEnabled": true } ``` **Success Response (201 Created)** ```json { "numberToMessageAppMapId": "NTMAP0000456", "messagingAppId": "webex-bot-12345", "phoneNumber": "+15551234567", "messagingAppType": "Webex", "mmsEnabled": true } ``` **cURL** ```bash curl -X POST "https://context-webex.sabrhub.com/api/v1/mapping/add/E0000123" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "messagingAppId": "webex-bot-12345", "phoneNumber": "+15551234567", "messagingAppType": "Webex", "mmsEnabled": true }' ``` ### **GET /mappings/enterprise/{enterpriseId}** List Mappings for an Enterprise **URL:** `GET https://context-webex.sabrhub.com/api/v1/mappings/enterprise/{enterpriseId}` **Success Response (200)** Array of Number Mapping objects. **cURL** ```bash curl -X GET "https://context-webex.sabrhub.com/api/v1/mappings/enterprise/E0000123" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ### **GET /mappings/csp/{cspId}** List Mappings for a CSP **URL:** `GET https://context-webex.sabrhub.com/api/v1/mappings/csp/{cspId}` Supports optional pagination and filters (`page`, `size`, `status`). Returns an array of Number Mapping objects. ### **DELETE /mapping/{mappingId}** Delete Mapping **URL:** `DELETE https://context-webex.sabrhub.com/api/v1/mapping/{mappingId}` **Success (204 No Content)** mapping removed. If the API returns a JSON message, treat `200` with a message as acceptable, but `204` is preferred. ```bash curl -X DELETE "https://context-webex.sabrhub.com/api/v1/mapping/NTMAP0000456" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` # **Webhooks (Inbound Events)** Integrators must implement an HTTPS endpoint to receive inbound message events (SMS → Webex flow). The platform will POST events to your webhook when messages arrive. > **Important:** Use HTTPS endpoints with valid TLS certificates. The platform may perform a verification handshake (challenge) — if you support webhook registration, implement a verification step that responds to challenge tokens. ### **Suggested webhook schema** **POST /webhooks/messages** (customer webhook endpoint — this is the endpoint you implement to receive events): ```json { "eventType": "message.received", "timestamp": "2025-10-14T12:00:00Z", "message": { "messageId": "MSG123456", "phoneNumber": "+15559871234", "from": "+15551230001", "to": "+15559871234", "text": "Hello, I need help", "media": [ { "url": "https://.../mms/abcd.jpg", "contentType": "image/jpeg" } ] }, "enterpriseId": "E0000123", "mappingId": "NTMAP0000456" } ``` **Response (200)** return HTTP 200 quickly to acknowledge receipt. If your endpoint is unavailable, our platform will retry according to exponential backoff rules. # **Error Codes & Handling** Standardize on a JSON `ErrorResponse`: ```json { "error": "Invalid phone number format", "code": "INVALID_PHONE", "details": { "field": "phoneNumber", "message": "Phone number must be E.164 format" } } ``` **Common HTTP status codes** * `200 OK` — successful GET or other operations that return a body. * `201 Created` — resource created (POST /enterprise, POST /mapping/add). * `204 No Content` — delete succeeded, no response body. * `400 Bad Request` — invalid input/data. * `401 Unauthorized` — missing or invalid token. * `403 Forbidden` — user lacks permission. * `404 Not Found` — resource not found (enterprise/mapping). * `429 Too Many Requests` — rate limit exceeded. * `500+` — server errors. # **Development vs Production Guidance** * **Development/Testing** * Use the development API base: `https://webex-dev-frontend.sabrhub.com/api/v1` * Use test phone numbers and test Webex bot identities. * Configure a local/ngrok HTTPS webhook endpoint for receiving events during development. * **Production** * Use the production API base: `https://context-webex.sabrhub.com/api/v1` * Ensure secure storage for `accessToken` and `refreshToken`. * Implement retries, logging, and monitoring for webhooks and API calls. **Environment switching** Use server variables or an environment config file for `API_BASE` so users cannot accidentally call production while testing. # **Best Practices & Recommendations** * **Use E.164 format** for phone numbers (e.g., `+15551234567`). * **Implement token refresh** using `/auth/getaccesstoken` before `accessToken` expiry. * **Handle retries and idempotency** for POSTs where the client may accidentally retry (use client-generated idempotency keys if supported). * **Log incoming webhook payloads** (temporarily in dev only) to aid debugging. * **Validate incoming messages** for allowed content and size, and sanitize text before forwarding to Webex. # **Examples Full Flow (Quick)** 1. **Login** (Auth): ```bash curl -X POST "https://usermanagement.sabrhub.com/v1/auth/login" \ -H "Content-Type: application/json" \ -d '{"username":"admin@csp.com","password":"YourPass"}' ``` 1. **Create enterprise** (API): ```bash curl -X POST "https://context-webex.sabrhub.com/api/v1/enterprise/CSP001" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"name":"BrightStar Marketing","contact":"Mike Chen","phoneNumber":"+15559871234","email":"mike@brightstar.com","defaultMmsSelection":true}' ``` 1. **Add mapping** ```bash curl -X POST "https://context-webex.sabrhub.com/api/v1/mapping/add/E0000124" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"messagingAppId":"brightstar-webex-bot","phoneNumber":"+15559871234","messagingAppType":"Webex","mmsEnabled":true}' ``` 1. **Test message** * Send SMS to `+15559871234` → webhook or Webex will receive and forward it to the mapped Webex bot/team. # **Operational Notes** * **Monitoring:** set up alerting if webhook delivery fails (exceeding retry thresholds) or if API rate limits are reached. * **Security:** rotate tokens periodically and do not store tokens in client-side code. * **Support:** when contacting support, include `enterpriseId` and `numberToMessageAppMapId` in your message to [support@sabrhub.com](mailto:support@sabrhub.com). # **Change Log** * **2025-10-14** Canonicalized hostnames, aligned mapping request/response fields, added webhook schema, standardized status codes, improved examples. # **Appendix: Quick Reference** * Auth: `POST https://usermanagement.sabrhub.com/v1/auth/login` * Refresh: `POST https://usermanagement.sabrhub.com/v1/auth/getaccesstoken` * Create enterprise: `POST https://context-webex.sabrhub.com/api/v1/enterprise/{cspId}` * Get enterprise: `GET https://context-webex.sabrhub.com/api/v1/enterprise/getenterprise/{enterpriseId}` * Delete enterprise: `DELETE https://context-webex.sabrhub.com/api/v1/enterprise/deleteenterprise/{enterpriseId}` * Add mapping: `POST https://context-webex.sabrhub.com/api/v1/mapping/add/{enterpriseId}` * List mappings (enterprise): `GET https://context-webex.sabrhub.com/api/v1/mappings/enterprise/{enterpriseId}` * List mappings (CSP): `GET https://context-webex.sabrhub.com/api/v1/mappings/csp/{cspId}` * Delete mapping: `DELETE https://context-webex.sabrhub.com/api/v1/mapping/{mappingId}`