Twitter Lead Gen API
Async job-based API. Submit a job, poll for status, retrieve results.
Important: When a job's 'view_url' is available, always share it with the user — it opens a spreadsheet GUI where they can browse, sort, and filter results visually.
Base URL
https://x-lead-gen-api-production.cloud.zoomgtm.com
Authentication
Two options (send one):
| Header | Source |
|---|---|
| 'x-officex-install-id' + 'x-officex-install-secret' | OfficeX install |
| 'x-api-key' | From '/auth/register' or '/auth/login' |
Core Workflow
''' POST /api/v1/jobs → 202 { job_id, status: "queued" } GET /api/v1/jobs/{job_id} → 200 { status: "processing"|"completed", ... } GET /api/v1/jobs/{job_id}/results → 200 { results: [...] } '''
1. Create Job
'''bash
curl -X POST $BASE/api/v1/jobs
-H "Content-Type: application/json"
-H "x-officex-install-id: $INSTALL_ID"
-H "x-officex-install-secret: $INSTALL_SECRET"
-d '{
"endpoint": "search",
"params": { "query": "AI startups" },
"max_records": 100
}'
'''
Request body:
'''json { "endpoint": "search", "params": { "query": "AI startups" }, "prompt_filter": "SaaS founders discussing pricing", "max_records": 100 } '''
| Field | Type | Required | Description |
|---|---|---|---|
| 'endpoint' | string | Yes | One of 29 endpoints below |
| 'params' | object or array | Yes | Endpoint params. Array for bulk (one task per item) |
| 'prompt_filter' | string | No | AI filter prompt (adds Gemini scoring, costs 0.12 instead of 0.1 credits/task) |
| 'max_records' | number | No | 1-1000, default 100. Auto-paginates to fetch this many results |
Response (202):
'''json { "job_id": "uuid", "status": "queued", "total_tasks": 4, "credits_reserved": 0.4, "poll_url": "/api/v1/jobs/{job_id}" } '''
2. Poll Status
'''bash curl $BASE/api/v1/jobs/{job_id} -H "x-api-key: $KEY" '''
Response:
'''json { "job_id": "uuid", "endpoint": "search", "status": "completed", "total_tasks": 4, "completed_tasks": 4, "failed_tasks": 0, "credits_per_task": 0.1, "credits_charged": 0.4, "params": { "query": "AI startups" }, "max_records": 100, "latest_cursor": "...", "created_at": "2025-01-25T10:00:00Z", "view_url": "https://example.com/dashboard/#/nc/view/uuid" } '''
'view_url' — opens a spreadsheet GUI (NocoDB) showing results for this job. Present it to the user so they can browse results visually. Only present once the job has started processing.
Status values: 'queued' | 'processing' | 'completed' | 'failed' | 'cancelled' | 'paused'
3. Get Results
'''bash curl "$BASE/api/v1/jobs/{job_id}/results?page=1&limit=50" -H "x-api-key: $KEY" '''
Response:
'''json { "job_id": "uuid", "endpoint": "search", "results": [ { "task_index": 0, "status": "success", "result_url": "https://s3.amazonaws.com/...", "item_urls": ["https://s3.amazonaws.com/..."], "credits_charged": 0.1, "match_score": 85, "ai_notes": "SaaS founder discussing B2B pricing" } ], "next_page": 2 } '''
'result_url' — full API response JSON. 'item_urls' — individual items (one per tweet/user/etc). 'match_score' and 'ai_notes' only present when 'prompt_filter' was used.
4. Control Jobs
'''bash
Pause
curl -X PATCH $BASE/api/v1/jobs/{job_id}
-H "x-api-key: $KEY" -H "Content-Type: application/json"
-d '{"status": "paused"}'
Resume
curl -X PATCH ... -d '{"status": "processing"}'
Cancel
curl -X PATCH ... -d '{"status": "cancelled"}' '''
Valid transitions: 'processing' → 'paused' → 'processing', any active → 'cancelled'.
5. Bookmark & Notes (per-item annotations)
Save bookmarks and notes on individual result items. Annotations persist in DynamoDB (result-rows table) and sync to the NocoDB spreadsheet view.
'''bash
Get all result rows (annotations) for a job
curl "$BASE/api/v1/jobs/{job_id}/result-rows" -H "x-api-key: $KEY" '''
Response:
'''json { "result_rows": [ { "job_id": "uuid", "sk": "0#0", "task_index": 0, "item_index": 0, "user_bookmarked": true, "user_notes": "Great lead", "updated_at": "...", "ttl": 1234567890 }, { "job_id": "uuid", "sk": "0#3", "task_index": 0, "item_index": 3, "user_bookmarked": false, "user_notes": "Follow up later", "updated_at": "...", "ttl": 1234567890 } ] } '''
'''bash
Bookmark or add notes to an item
curl -X PATCH "$BASE/api/v1/jobs/{job_id}/results/0/items/3"
-H "x-api-key: $KEY" -H "Content-Type: application/json"
-d '{"user_bookmarked": true, "user_notes": "Promising SaaS founder"}'
'''
Response:
'''json { "success": true, "job_id": "uuid", "task_index": 0, "item_index": 3, "user_bookmarked": true, "user_notes": "Promising SaaS founder" } '''
Both fields are optional — send either or both. 'view_url' spreadsheet includes 'user_bookmarked' and 'user_notes' columns that sync automatically.
5b. NocoDB Webhook (2-way sync)
'''bash
NocoDB calls this when a user edits annotations in the spreadsheet
curl -X POST "$BASE/api/v1/webhooks/nocodb"
-H "x-webhook-secret: $NOCODB_WEBHOOK_SECRET"
-H "Content-Type: application/json"
-d '{"data":{"row":{"job_id":"uuid","task_index":0,"item_index":3,"user_bookmarked":true}}}'
'''
Anti-loop: webhook writes to DynamoDB only, never syncs back to NocoDB.
5c. Legacy Endpoints (deprecated)
The following endpoints still work but are deprecated. Use the new endpoints above.
'''bash
DEPRECATED: Get annotations (use GET /result-rows instead)
curl "$BASE/api/v1/jobs/{job_id}/items" -H "x-api-key: $KEY"
DEPRECATED: Patch annotation (use PATCH /results/{task_index}/items/{item_index} instead)
curl -X PATCH "$BASE/api/v1/jobs/{job_id}/items/0:3"
-H "x-api-key: $KEY" -H "Content-Type: application/json"
-d '{"user_bookmarked": true}'
'''
Endpoints (29)
User Endpoints
| Endpoint | Required | Optional | Returns |
|---|---|---|---|
| 'user-info' | screenname | rest_id | Single user profile |
| 'bulk-users' | rest_ids | — | Multiple user profiles |
| 'about-profile' | screenname | — | Extended profile info |
| 'following' | screenname | cursor | Paginated user list |
| 'followers' | screenname | blue_verified, cursor | Paginated user list |
| 'affiliates' | screenname | cursor | Paginated user list |
| 'check-follow' | screenname, target | — | Follow relationship |
Tweet Endpoints
| Endpoint | Required | Optional | Returns |
|---|---|---|---|
| 'search' | query | search_type, cursor | Paginated tweets |
| 'timeline' | screenname | cursor | Paginated tweets |
| 'usermedia' | screenname | cursor | Paginated media tweets |
| 'replies' | screenname | cursor | Paginated replies |
| 'tweet-info' | id | — | Single tweet |
| 'tweet-thread' | id | — | Tweet thread |
| 'latest-replies' | id | cursor | Paginated replies |
| 'retweets' | id | cursor | Paginated users |
| 'check-retweet' | id, screenname | — | Retweet check |
| 'top-posts' | type | country, period | Paginated tweets |
'search_type': Top, Latest, People, Photos, Videos. 'type' (top-posts): Likes, Retweets. 'period': Daily, Weekly, Monthly.
List Endpoints
| Endpoint | Required | Optional | Returns |
|---|---|---|---|
| 'list-timeline' | list_id | cursor | Paginated tweets |
| 'list-followers' | list_id | cursor | Paginated users |
| 'list-members' | list_id | cursor | Paginated users |
Community Endpoints
| Endpoint | Required | Optional | Returns |
|---|---|---|---|
| 'community-timeline' | community_id | ranking, cursor | Paginated tweets |
| 'community-members' | community_id | cursor | Paginated users |
| 'search-communities' | query | — | Community list |
| 'communities-latest' | query | cursor | Paginated tweets |
| 'communities-top' | query | cursor | Paginated tweets |
'ranking': Top, New.
Other Endpoints
| Endpoint | Required | Optional | Returns |
|---|---|---|---|
| 'trends' | country | — | Trending topics |
| 'jobs' | query | — | Job listings |
| 'spaces' | id | — | Space details |
| 'broadcast' | rest_id | — | Broadcast info |
Bulk Requests
Pass 'params' as an array to create one task per item:
'''json { "endpoint": "user-info", "params": [ { "screenname": "elonmusk" }, { "screenname": "sama" }, { "screenname": "sataborasu" } ] } '''
Creates 3 tasks. Each task is billed independently.
Billing
| Type | Credits/Task | USD/Task |
|---|---|---|
| Without AI filter | 0.1 | $0.001 |
| With 'prompt_filter' | 0.12 | $0.0012 |
Credits are reserved upfront, settled progressively as tasks complete. Failed tasks are not billed. Unused credits are refunded on completion/cancellation.
Auth Endpoints
POST '/auth/register'
'''json { "email": "user@example.com", "password": "min6chars" } ''' → '201 { api_key, install_id, email }'
POST '/auth/login'
'''json { "email": "user@example.com", "password": "..." } ''' → '200 { api_key, install_id, email }'
POST '/auth/officex-login'
'''json { "officex_customer_id": "uuid", "install_id": "uuid", "install_secret": "..." } ''' → '200 { api_key, install_id, install_secret }'
All Routes
| Method | Path | Description |
|---|---|---|
| POST | '/auth/register' | Create account |
| POST | '/auth/login' | Login |
| POST | '/auth/officex-login' | OfficeX autologin |
| POST | '/api/v1/jobs' | Create job |
| GET | '/api/v1/jobs' | List jobs ('?page=&limit=') |
| GET | '/api/v1/jobs/{job_id}' | Job status |
| PATCH | '/api/v1/jobs/{job_id}' | Update job (pause/resume/cancel) |
| GET | '/api/v1/jobs/{job_id}/results' | Results ('?page=&limit=') |
| GET | '/api/v1/jobs/{job_id}/results/{task_index}' | Single result |
| GET | '/api/v1/jobs/{job_id}/result-rows' | Get all result rows (annotations) |
| PATCH | '/api/v1/jobs/{job_id}/results/{task_index}/items/{item_index}' | Update item bookmark/notes |
| POST | '/api/v1/webhooks/nocodb' | NocoDB 2-way sync webhook |
| GET | '/api/v1/jobs/{job_id}/items' | Deprecated — Get item annotations |
| PATCH | '/api/v1/jobs/{job_id}/items/{item_key}' | Deprecated — Update item bookmark/notes |
| GET | '/docs' | Raw skill markdown |
| POST | '/webhooks/officex' | OfficeX lifecycle webhooks |
Error Codes
| Code | Meaning |
|---|---|
| 400 | Invalid request (validation error) |
| 401 | Missing or invalid auth |
| 402 | Insufficient credits |
| 403 | Installation expired |
| 404 | Job or result not found |
| 409 | Email already registered |
| 429 | Rate limited |
All errors return: '{ "error": "Human-readable message" }'
Data Retention
Results stored for 90 days in S3.