Files
pos-system/services/mkt-x-service-net/docs/en/API.md

1729 lines
26 KiB
Markdown

# 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