# X/Twitter Marketing Service - API Documentation ## Table of Contents 1. [API Overview](#api-overview) 2. [Authentication](#authentication) 3. [Account Management](#account-management) 4. [Contact Management](#contact-management) 5. [Conversation Management](#conversation-management) 6. [Template Management](#template-management) 7. [Campaign Management](#campaign-management) 8. [Segment Management](#segment-management) 9. [Automation Flows](#automation-flows) 10. [AI Chatbot](#ai-chatbot) 11. [Analytics](#analytics) 12. [Webhooks](#webhooks) 13. [Error Handling](#error-handling) --- ## API Overview ### Base URL ``` Development: http://localhost:5000/api/v1/mkt-x Production: https://api.goodgo.com/api/v1/mkt-x ``` ### Versioning API versioning is handled through the URL path (`/api/v1/`). ### Request Format All requests with body should use: ``` Content-Type: application/json ``` ### Response Format All responses follow this structure: **Success Response** ```json { "success": true, "data": { ... }, "pagination": { "page": 1, "limit": 20, "total": 100, "totalPages": 5 } } ``` **Error Response** ```json { "success": false, "error": "Error message description" } ``` --- ## Authentication ### JWT Bearer Token All API endpoints (except webhooks) require authentication via JWT bearer token. **Request Header** ``` Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` ### Obtaining Token Tokens are obtained from the IAM service: ```bash POST /api/v1/auth/login Content-Type: application/json { "email": "user@example.com", "password": "password" } ``` **Response** ```json { "success": true, "data": { "accessToken": "eyJhbGci...", "refreshToken": "refresh...", "expiresIn": 3600 } } ``` --- ## Account Management ### Connect Twitter Account Connect a Twitter account using OAuth 1.0a credentials. **Endpoint** ``` POST /accounts ``` **Request Body** ```json { "oauthToken": "oauth_token_from_twitter", "oauthTokenSecret": "oauth_token_secret_from_twitter" } ``` **Response** `200 OK` ```json { "success": true, "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "merchantId": "merchant-uuid", "twitterUserId": "123456789", "username": "goodgo_shop", "displayName": "GoodGo Official", "status": "active", "connectedAt": "2026-01-18T10:00:00Z" } } ``` **Error Codes** - `400` - Invalid OAuth credentials - `401` - Unauthorized - `409` - Account already connected --- ### List Connected Accounts Get all Twitter accounts connected by the merchant. **Endpoint** ``` GET /accounts ``` **Query Parameters** - `status` (optional) - Filter by status: `active`, `inactive`, `error` **Response** `200 OK` ```json { "success": true, "data": [ { "id": "uuid", "merchantId": "uuid", "twitterUserId": "123456789", "username": "goodgo_shop", "displayName": "GoodGo Official", "status": "active", "connectedAt": "2026-01-18T10:00:00Z" } ] } ``` --- ### Get Account Details Get detailed information about a specific Twitter account. **Endpoint** ``` GET /accounts/{accountId} ``` **Response** `200 OK` ```json { "success": true, "data": { "id": "uuid", "merchantId": "uuid", "twitterUserId": "123456789", "username": "goodgo_shop", "displayName": "GoodGo Official", "profileImageUrl": "https://pbs.twimg.com/profile_images/...", "status": "active", "webhookId": "webhook-id", "connectedAt": "2026-01-18T10:00:00Z", "statistics": { "totalContacts": 1234, "totalConversations": 567, "messagesThisMonth": 890 } } } ``` **Error Codes** - `404` - Account not found --- ### Disconnect Account Disconnect a Twitter account and revoke OAuth tokens. **Endpoint** ``` DELETE /accounts/{accountId} ``` **Response** `200 OK` ```json { "success": true, "data": null } ``` --- ### Update Account Settings Update account configuration settings. **Endpoint** ``` PUT /accounts/{accountId} ``` **Request Body** ```json { "autoReplyEnabled": true, "businessHours": { "enabled": true, "timezone": "Asia/Ho_Chi_Minh", "schedule": { "monday": { "start": "09:00", "end": "18:00" }, "tuesday": { "start": "09:00", "end": "18:00" } } } } ``` **Response** `200 OK` --- ## Contact Management ### List Contacts Get paginated list of contacts with filtering. **Endpoint** ``` GET /contacts ``` **Query Parameters** - `accountId` (optional) - Filter by Twitter account - `tags` (optional) - Comma-separated tags: `vip,customer` - `search` (optional) - Search in username/display name - `skip` (optional, default: 0) - Pagination offset - `take` (optional, default: 20, max: 100) - Items per page **Response** `200 OK` ```json { "success": true, "data": [ { "id": "uuid", "accountId": "uuid", "twitterUserId": "987654321", "username": "customer_john", "displayName": "John Doe", "profileImageUrl": "https://...", "tags": ["vip", "customer"], "attributes": { "purchaseCount": 5, "totalSpent": 1250000, "lastPurchaseDate": "2026-01-15" }, "conversationCount": 3, "firstInteractionAt": "2025-12-01T10:00:00Z", "lastInteractionAt": "2026-01-18T09:30:00Z" } ], "pagination": { "page": 1, "limit": 20, "total": 1234, "totalPages": 62 } } ``` --- ### Get Contact Details Get detailed information about a specific contact. **Endpoint** ``` GET /contacts/{contactId} ``` **Response** `200 OK` ```json { "success": true, "data": { "id": "uuid", "accountId": "uuid", "twitterUserId": "987654321", "username": "customer_john", "displayName": "John Doe", "profileImageUrl": "https://...", "tags": ["vip", "customer"], "attributes": { "purchaseCount": 5, "totalSpent": 1250000, "lastPurchaseDate": "2026-01-15", "preferredLanguage": "vi" }, "source": "inbound_message", "conversationCount": 3, "firstInteractionAt": "2025-12-01T10:00:00Z", "lastInteractionAt": "2026-01-18T09:30:00Z", "engagement": { "messagesSent": 15, "messagesReceived": 18, "averageResponseTime": "5m 30s" } } } ``` --- ### Update Contact Update contact information. **Endpoint** ``` PUT /contacts/{contactId} ``` **Request Body** ```json { "displayName": "John Doe (VIP)", "attributes": { "preferredLanguage": "en", "notes": "Premium customer" } } ``` **Response** `200 OK` --- ### Add Tags to Contact Add one or more tags to a contact. **Endpoint** ``` POST /contacts/{contactId}/tags ``` **Request Body** ```json { "tags": ["vip", "premium"] } ``` **Response** `200 OK` --- ### Remove Tag from Contact Remove a specific tag from a contact. **Endpoint** ``` DELETE /contacts/{contactId}/tags/{tagName} ``` **Response** `200 OK` --- ### Update Contact Attributes Bulk update custom attributes for a contact. **Endpoint** ``` PUT /contacts/{contactId}/attributes ``` **Request Body** ```json { "attributes": { "purchaseCount": 6, "totalSpent": 1500000, "lastPurchaseDate": "2026-01-18", "membershipTier": "gold" } } ``` **Response** `200 OK` --- ### Get Contact Conversations Get all conversations for a specific contact. **Endpoint** ``` GET /contacts/{contactId}/conversations ``` **Query Parameters** - `status` (optional) - Filter by status: `open`, `closed` - `skip` (optional) - Pagination offset - `take` (optional) - Items per page **Response** `200 OK` ```json { "success": true, "data": [ { "id": "uuid", "contactId": "uuid", "status": "open", "messageCount": 5, "startedAt": "2026-01-18T09:00:00Z", "lastMessageAt": "2026-01-18T09:30:00Z" } ] } ``` --- ### Delete Contact Delete a contact and all associated data (GDPR compliance). **Endpoint** ``` DELETE /contacts/{contactId} ``` **Response** `200 OK` --- ## Conversation Management ### List Conversations Get paginated list of conversations. **Endpoint** ``` GET /conversations ``` **Query Parameters** - `accountId` (optional) - Filter by account - `status` (optional) - Filter by status: `open`, `closed` - `assignedTo` (optional) - Filter by assigned user ID - `skip` (optional) - Pagination offset - `take` (optional) - Items per page **Response** `200 OK` ```json { "success": true, "data": [ { "id": "uuid", "contactId": "uuid", "accountId": "uuid", "status": "open", "channel": "direct_message", "assignedToUserId": "uuid", "messageCount": 12, "startedAt": "2026-01-18T09:00:00Z", "lastMessageAt": "2026-01-18T10:15:00Z", "contact": { "username": "customer_john", "displayName": "John Doe" } } ], "pagination": { ... } } ``` --- ### Get Conversation with Messages Get conversation details including all messages. **Endpoint** ``` GET /conversations/{conversationId} ``` **Query Parameters** - `includeMessages` (optional, default: true) - Include message history **Response** `200 OK` ```json { "success": true, "data": { "id": "uuid", "contactId": "uuid", "accountId": "uuid", "status": "open", "channel": "direct_message", "assignedToUserId": "uuid", "startedAt": "2026-01-18T09:00:00Z", "messages": [ { "id": "uuid", "conversationId": "uuid", "direction": "inbound", "type": "text", "content": "Hello, I have a question about my order", "attachments": [], "isFromBot": false, "sentAt": "2026-01-18T09:00:00Z" }, { "id": "uuid", "conversationId": "uuid", "direction": "outbound", "type": "text", "content": "Hi! I'd be happy to help. What's your order number?", "attachments": [], "isFromBot": false, "sentAt": "2026-01-18T09:02:00Z" } ] } } ``` --- ### Send Message Send a message in a conversation. **Endpoint** ``` POST /conversations/{conversationId}/messages ``` **Request Body** ```json { "content": "Your order #12345 has been shipped!", "type": "text", "attachments": [ { "type": "image", "url": "https://example.com/tracking.png" } ] } ``` **Response** `200 OK` ```json { "success": true, "data": { "id": "uuid", "conversationId": "uuid", "twitterMessageId": "123456789", "direction": "outbound", "type": "text", "content": "Your order #12345 has been shipped!", "sentAt": "2026-01-18T10:30:00Z" } } ``` **Error Codes** - `400` - Message content exceeds Twitter limits (10,000 chars) - `429` - Rate limit exceeded --- ### Close Conversation Close an active conversation. **Endpoint** ``` PUT /conversations/{conversationId}/close ``` **Request Body** (optional) ```json { "reason": "resolved" } ``` **Response** `200 OK` --- ### Assign Conversation Assign conversation to a specific user/agent. **Endpoint** ``` POST /conversations/{conversationId}/assign ``` **Request Body** ```json { "userId": "user-uuid" } ``` **Response** `200 OK` --- ## Template Management ### Create Template Create a new message template. **Endpoint** ``` POST /templates ``` **Request Body** ```json { "name": "Welcome Message", "type": "text", "content": "Hi {{name}}, welcome to {{shop_name}}! Use code {{discount_code}} for 10% off your first order.", "variables": ["name", "shop_name", "discount_code"] } ``` **Response** `200 OK` ```json { "success": true, "data": { "id": "uuid", "merchantId": "uuid", "name": "Welcome Message", "type": "text", "content": "Hi {{name}}, welcome to...", "variables": ["name", "shop_name", "discount_code"], "createdAt": "2026-01-18T10:00:00Z" } } ``` --- ### List Templates Get all templates for the merchant. **Endpoint** ``` GET /templates ``` **Query Parameters** - `type` (optional) - Filter by type: `text`, `quick_reply`, `card` - `search` (optional) - Search in template name **Response** `200 OK` --- ### Get Template Get template details. **Endpoint** ``` GET /templates/{templateId} ``` **Response** `200 OK` --- ### Update Template Update existing template. **Endpoint** ``` PUT /templates/{templateId} ``` **Request Body** ```json { "name": "Updated Welcome Message", "content": "Hello {{name}}!..." } ``` **Response** `200 OK` --- ### Delete Template Delete a template. **Endpoint** ``` DELETE /templates/{templateId} ``` **Response** `200 OK` **Error Codes** - `409` - Template is being used by active campaigns --- ### Preview Template Preview rendered template with sample data. **Endpoint** ``` POST /templates/{templateId}/preview ``` **Request Body** ```json { "variables": { "name": "John", "shop_name": "GoodGo Shop", "discount_code": "WELCOME10" } } ``` **Response** `200 OK` ```json { "success": true, "data": { "rendered": "Hi John, welcome to GoodGo Shop! Use code WELCOME10 for 10% off your first order." } } ``` --- ## Campaign Management ### Create Campaign Create a new marketing campaign. **Endpoint** ``` POST /campaigns ``` **Request Body** ```json { "name": "January Promotion", "type": "promotional", "templateId": "template-uuid", "segmentIds": ["segment-uuid-1", "segment-uuid-2"], "schedule": { "startAt": "2026-01-20T10:00:00Z", "endAt": null, "recurrence": null } } ``` **Response** `200 OK` ```json { "success": true, "data": { "id": "uuid", "merchantId": "uuid", "name": "January Promotion", "type": "promotional", "status": "draft", "templateId": "uuid", "segmentIds": ["uuid"], "schedule": { ... }, "metrics": { "totalSent": 0, "delivered": 0, "opened": 0, "clicked": 0, "replied": 0, "failed": 0 }, "createdAt": "2026-01-18T10:00:00Z" } } ``` --- ### List Campaigns Get all campaigns. **Endpoint** ``` GET /campaigns ``` **Query Parameters** - `status` (optional) - Filter: `draft`, `scheduled`, `running`, `paused`, `completed` - `type` (optional) - Filter: `promotional`, `transactional`, `engagement` **Response** `200 OK` --- ### Get Campaign Get campaign details. **Endpoint** ``` GET /campaigns/{campaignId} ``` **Response** `200 OK` --- ### Update Campaign Update campaign (only for draft/scheduled campaigns). **Endpoint** ``` PUT /campaigns/{campaignId} ``` **Request Body** ```json { "name": "Updated Campaign Name", "schedule": { "startAt": "2026-01-21T10:00:00Z" } } ``` **Response** `200 OK` **Error Codes** - `400` - Cannot update running/completed campaigns --- ### Start Campaign Start campaign execution. **Endpoint** ``` POST /campaigns/{campaignId}/start ``` **Response** `200 OK` **Error Codes** - `400` - Campaign has no segments or invalid template --- ### Pause Campaign Pause a running campaign. **Endpoint** ``` POST /campaigns/{campaignId}/pause ``` **Response** `200 OK` --- ### Resume Campaign Resume a paused campaign. **Endpoint** ``` POST /campaigns/{campaignId}/resume ``` **Response** `200 OK` --- ### Get Campaign Metrics Get detailed campaign performance metrics. **Endpoint** ``` GET /campaigns/{campaignId}/metrics ``` **Response** `200 OK` ```json { "success": true, "data": { "totalSent": 1500, "delivered": 1450, "opened": 800, "clicked": 250, "replied": 45, "failed": 50, "openRate": 0.55, "clickRate": 0.17, "replyRate": 0.03, "deliveryRate": 0.97, "timeline": [ { "timestamp": "2026-01-20T10:00:00Z", "sent": 500, "delivered": 485 } ] } } ``` --- ### Send Test Campaign Send test message to specific contacts. **Endpoint** ``` POST /campaigns/{campaignId}/test ``` **Request Body** ```json { "contactIds": ["contact-uuid-1", "contact-uuid-2"], "variables": { "discount_code": "TEST10" } } ``` **Response** `200 OK` --- ## Segment Management ### Create Segment Create a customer segment with conditions. **Endpoint** ``` POST /segments ``` **Request Body** ```json { "name": "VIP Customers", "conditions": [ { "field": "tags", "operator": "contains", "value": "vip" }, { "field": "attributes.purchaseCount", "operator": "greaterThan", "value": 5 }, { "field": "lastInteractionAt", "operator": "after", "value": "2026-01-01T00:00:00Z" } ] } ``` **Response** `200 OK` ```json { "success": true, "data": { "id": "uuid", "merchantId": "uuid", "name": "VIP Customers", "conditions": [ ... ], "contactCount": 0, "createdAt": "2026-01-18T10:00:00Z" } } ``` --- ### List Segments Get all segments. **Endpoint** ``` GET /segments ``` **Response** `200 OK` --- ### Get Segment Get segment details. **Endpoint** ``` GET /segments/{segmentId} ``` **Response** `200 OK` --- ### Update Segment Update segment conditions. **Endpoint** ``` PUT /segments/{segmentId} ``` **Request Body** ```json { "name": "Updated VIP Customers", "conditions": [ ... ] } ``` **Response** `200 OK` --- ### Delete Segment Delete a segment. **Endpoint** ``` DELETE /segments/{segmentId} ``` **Response** `200 OK` **Error Codes** - `409` - Segment is being used by active campaigns --- ### Preview Segment Contacts Preview contacts that match segment conditions. **Endpoint** ``` POST /segments/{segmentId}/preview ``` **Query Parameters** - `limit` (optional, default: 10, max: 50) - Number of contacts to preview **Response** `200 OK` ```json { "success": true, "data": { "totalMatches": 234, "preview": [ { "id": "uuid", "username": "customer_john", "displayName": "John Doe", "tags": ["vip"], "attributes": { "purchaseCount": 8 } } ] } } ``` --- ## Automation Flows ### Create Automation Flow Create a new automation workflow. **Endpoint** ``` POST /automation/flows ``` **Request Body** ```json { "name": "Welcome Flow", "trigger": { "type": "new_follower", "config": {} }, "nodes": [ { "id": "node-1", "type": "send_message", "config": { "templateId": "template-uuid", "delay": 0 } }, { "id": "node-2", "type": "wait", "config": { "duration": 86400 } }, { "id": "node-3", "type": "send_message", "config": { "templateId": "template-uuid-2", "delay": 0 } } ], "connections": [ { "fromNodeId": "node-1", "toNodeId": "node-2" }, { "fromNodeId": "node-2", "toNodeId": "node-3" } ] } ``` **Response** `200 OK` --- ### List Automation Flows Get all automation flows. **Endpoint** ``` GET /automation/flows ``` **Query Parameters** - `status` (optional) - Filter: `active`, `inactive`, `draft` **Response** `200 OK` --- ### Get Automation Flow Get flow details. **Endpoint** ``` GET /automation/flows/{flowId} ``` **Response** `200 OK` --- ### Update Automation Flow Update flow configuration. **Endpoint** ``` PUT /automation/flows/{flowId} ``` **Request Body** ```json { "name": "Updated Welcome Flow", "nodes": [ ... ], "connections": [ ... ] } ``` **Response** `200 OK` **Error Codes** - `400` - Cannot update active flows (deactivate first) --- ### Activate Flow Activate an automation flow. **Endpoint** ``` POST /automation/flows/{flowId}/activate ``` **Response** `200 OK` --- ### Deactivate Flow Deactivate a running flow. **Endpoint** ``` POST /automation/flows/{flowId}/deactivate ``` **Response** `200 OK` --- ### Delete Flow Delete an automation flow. **Endpoint** ``` DELETE /automation/flows/{flowId} ``` **Response** `200 OK` --- ### Get Flow Executions Get execution history for a flow. **Endpoint** ``` GET /automation/flows/{flowId}/executions ``` **Query Parameters** - `status` (optional) - Filter: `running`, `completed`, `failed` - `skip`, `take` - Pagination **Response** `200 OK` ```json { "success": true, "data": [ { "id": "uuid", "flowId": "uuid", "contactId": "uuid", "status": "completed", "currentNodeId": null, "startedAt": "2026-01-18T09:00:00Z", "completedAt": "2026-01-19T09:00:00Z" } ] } ``` --- ## AI Chatbot ### Send Message to AI Send a message to AI chatbot for processing. **Endpoint** ``` POST /ai/conversations/{conversationId}/message ``` **Request Body** ```json { "message": "What's the status of my order #12345?" } ``` **Response** `200 OK` ```json { "success": true, "data": { "intent": "order_status_query", "confidence": 0.95, "response": "Let me check that for you. Order #12345 was shipped on January 15 and is expected to arrive on January 20.", "slots": { "orderId": "12345" }, "requiresEscalation": false } } ``` --- ### Get Conversation Context Get AI conversation context. **Endpoint** ``` GET /ai/conversations/{conversationId}/context ``` **Response** `200 OK` ```json { "success": true, "data": { "sessionId": "uuid", "context": [ { "role": "user", "content": "What's the status of my order?" }, { "role": "assistant", "content": "I'd be happy to help! What's your order number?" } ], "currentIntent": "order_status_query", "slots": { "orderId": "12345" } } } ``` --- ### Escalate to Human Escalate AI conversation to human agent. **Endpoint** ``` POST /ai/conversations/{conversationId}/escalate ``` **Request Body** ```json { "reason": "complex_query" } ``` **Response** `200 OK` --- ### Update AI Settings Update AI chatbot settings for the merchant. **Endpoint** ``` PUT /ai/settings ``` **Request Body** ```json { "enabled": true, "model": "gpt-4", "temperature": 0.7, "maxTokens": 500, "autoEscalationThreshold": 0.6, "systemPrompt": "You are a helpful customer service assistant for GoodGo Shop..." } ``` **Response** `200 OK` --- ## Analytics ### Get Overview Analytics Get dashboard overview analytics. **Endpoint** ``` GET /analytics/overview ``` **Query Parameters** - `startDate` (required) - ISO 8601 date - `endDate` (required) - ISO 8601 date - `accountId` (optional) - Filter by account **Response** `200 OK` ```json { "success": true, "data": { "period": { "startDate": "2026-01-01T00:00:00Z", "endDate": "2026-01-18T23:59:59Z" }, "contacts": { "total": 1234, "new": 156, "active": 456 }, "conversations": { "total": 567, "open": 45, "closed": 522, "averageResponseTime": "5m 30s" }, "campaigns": { "active": 3, "completed": 12, "totalMessagesSent": 15000 }, "automation": { "activeFlows": 5, "totalExecutions": 890 } } } ``` --- ### Get Contact Analytics Get contact-related analytics. **Endpoint** ``` GET /analytics/contacts ``` **Query Parameters** - `startDate`, `endDate` - Date range - `groupBy` (optional) - Group by: `day`, `week`, `month` **Response** `200 OK` --- ### Get Conversation Analytics Get conversation analytics. **Endpoint** ``` GET /analytics/conversations ``` **Response** `200 OK` --- ### Get Campaign Analytics Get campaign performance analytics. **Endpoint** ``` GET /analytics/campaigns ``` **Query Parameters** - `campaignId` (optional) - Specific campaign - `startDate`, `endDate` - Date range **Response** `200 OK` --- ### Get Automation Analytics Get automation flow analytics. **Endpoint** ``` GET /analytics/automation ``` **Response** `200 OK** --- ## Webhooks ### Receive Twitter Webhook Events Endpoint for receiving Twitter webhook events (Account Activity API). **Endpoint** ``` POST /webhooks/twitter ``` **Headers** ``` X-Twitter-Webhooks-Signature: sha256=... ``` **Request Body** (example: Direct Message Event) ```json { "direct_message_events": [ { "id": "123456789", "created_timestamp": "1642000000000", "message_create": { "sender_id": "987654321", "target": { "recipient_id": "123456789" }, "message_data": { "text": "Hello!", "entities": {} } } } ], "users": { "987654321": { "id": "987654321", "screen_name": "customer_john", "name": "John Doe" } } } ``` **Response** `200 OK` **Note**: This endpoint validates the Twitter signature for security. --- ### Twitter CRC Verification Twitter Challenge-Response Check for webhook verification. **Endpoint** ``` GET /webhooks/verify ``` **Query Parameters** - `crc_token` - Token from Twitter **Response** `200 OK` ```json { "response_token": "sha256=base64_encoded_hmac" } ``` --- ## Error Handling ### HTTP Status Codes | Code | Meaning | Description | |------|---------|-------------| | 200 | OK | Request successful | | 201 | Created | Resource created | | 400 | Bad Request | Invalid request parameters | | 401 | Unauthorized | Missing or invalid auth token | | 403 | Forbidden | Insufficient permissions | | 404 | Not Found | Resource not found | | 409 | Conflict | Resource already exists or conflict | | 422 | Unprocessable Entity | Validation failed | | 429 | Too Many Requests | Rate limit exceeded | | 500 | Internal Server Error | Server error | | 503 | Service Unavailable | Service temporarily unavailable | ### Error Response Format ```json { "success": false, "error": "Detailed error message", "code": "ERROR_CODE", "details": { "field": "templateId", "reason": "Template not found" } } ``` ### Common Error Codes | Code | Description | |------|-------------| | `VALIDATION_ERROR` | Request validation failed | | `UNAUTHORIZED` | Authentication required | | `FORBIDDEN` | Insufficient permissions | | `RESOURCE_NOT_FOUND` | Requested resource not found | | `DUPLICATE_RESOURCE` | Resource already exists | | `RATE_LIMIT_EXCEEDED` | Too many requests | | `TWITTER_API_ERROR` | Twitter API error | | `AI_SERVICE_ERROR` | AI service error | ### Rate Limiting **Headers** ``` X-RateLimit-Limit: 100 X-RateLimit-Remaining: 95 X-RateLimit-Reset: 1642000000 ``` **Limits** - API calls: 100 requests/minute per merchant - Campaigns: 10,000 messages/day per account - Messages: 500 messages/24 hours per Twitter account (Twitter limit) --- ## Postman Collection Download the complete Postman collection for testing: ``` https://api.goodgo.com/api/v1/mkt-x/postman-collection.json ``` --- ## Support For API support, contact: api-support@goodgo.com