X Write
Send DM
Send X direct messages from a connected account, store messageId, and attach one uploaded media ID
POST
Send DM
10 credits per call · All plans from $0.00012/credit
userId. For media DMs, upload first with POST /x/media, pass the returned mediaId as the only media_ids item, and store the returned messageId. Use public media URLs with POST /x/tweets; this DM endpoint accepts one uploaded media ID instead.
message_id, user_id, account, send_status, optional media_id,
media_ids, and source_endpoint. For media DMs, keep media_ids as the
one-item request array and set media_id to the uploaded media ID that you
passed as that single item.
Send with media
Upload media first with Upload Media, then pass the returnedmediaId as the only media_ids item.
reply_to_message_id while the REST route rejects it.
Leave it unset. Pass exactly one uploaded media ID in media_ids, then store
the returned messageId with that media ID.
Media DM result handoff
After the media DM send returns200 OK, store the returned messageId with the uploaded media ID and recipient user ID so support logs, CRM records, queues, or agent memory can reconcile the attachment with the sent message.
media_ids as a one-item array in the request, keep media_id as the original POST /x/media result, and use message_id as the external DM identifier after the send succeeds.
Direct message handoff
UsePOST /x/dm/{userId} when a support, sales, community, CRM, or agent workflow needs to send an auditable direct message from a connected X account. If you only have a username, look up the recipient first with GET /x/users/{id}. If the workflow needs conversation context, read the latest messages with GET /x/dm/{userId}/history before sending.
messageId
Store
messageId as the external message ID for support logs, CRM records, queues, or agent memory.success
Mark the send job complete after a
200 OK response.userId
Keep the recipient X user ID from the path with the send job.
account
Store the connected X account that sent the DM.
text
Store the exact message text sent. Add your own
sent_at timestamp when downstream systems need it.media_ids[0]
Store the uploaded media ID when the DM includes one attachment from
POST /x/media.POST /x/media is a separate 10-credit call. x_dm_not_allowed means the recipient may not accept messages from this connected account; do not retry unchanged. Do not retry 422 x_dm_not_allowed unchanged. Use another permitted connected account or ask the recipient to allow messages.
Open the Direct Message Workflow for queue design. Use Get DM History for approved conversation context. Use Upload Media to create the one mediaId allowed in media_ids.
Headers
string
required
Your API key. Session cookie authentication is also supported. Generate a key from the dashboard.
string
required
Unique key for this intended write. Reuse it only for an exact network replay.
string
required
Must be
application/json.Path parameters
string
required
The X user ID of the recipient.
Body
string
required
X username or account ID of your connected account to act as.
string
required
Non-empty message text to send. If X rejects oversized content, the API
returns
422 x_content_too_long.string[]
Optional one-item array containing an uploaded media ID. Upload media first with Upload Media, then pass the returned
mediaId as the only array item. Empty arrays and multiple IDs are rejected.Response
Durable lifecycle responses
Store the
X-Request-Id response header with every action record.- Store
id,request.hash,account,target, andbilling. - Stop only when
terminalistrue. - Poll
statusUrlafterRetry-AfterorpollAfterMs. - Retry only when
safeToRetryistrue. - Use a new key only for a newly approved write.
- 200 Terminal
- 202 Active
- 400 Invalid Input
- 401 Unauthenticated
- 402 Billing Required
- 403 Account Blocked
- 409 Idempotency conflict
- 422 Write Rejected
- 429 Rate Limited
- 500 Write Failed
The action reached
success, failed, or expired. Trust terminal,
result, billing, and nextAction over the HTTP class.string
Always
x_write_action.string
Durable action ID.
string
Compatibility alias for
id.string
Exact write operation.
string
Current lifecycle status.
boolean
Whether polling can stop.
boolean
Whether a later attempt could succeed.
boolean
Whether a new attempt is safe.
string
Relative polling URL.
number | null
Recommended polling delay.
boolean
Whether billing settled as charged.
string
Settled credits charged.
object
Planned and settled billing state.
object
Stable hash and exact sanitized payload.
object
Exact connected account selected.
object | null
Exact target type and ID.
string | null
Compatibility target ID.
object | null
Confirmed result or desired state.
object | null
Required poll, retry, or verification step.
string
Stable request fingerprint.
string
Correlation ID.
boolean
Whether this response replayed an existing action.
string
Machine-readable error code.
string
Actionable status or error message.
boolean
Whether dispatch occurred.
string
ISO 8601 dispatch time.
string
ISO 8601 creation time.
string
ISO 8601 latest update time.
string
ISO 8601 terminal time.
string
Nonterminal resolution deadline.
string
ISO 8601 confirmation time.
string
ISO 8601 latest confirmation check.
number
Confirmation attempt count.
string
Confirmed tweet ID when available.
string
Confirmed direct message ID when available.
string
Confirmed media ID when available.
string
Public media URL when available.
string
Confirmed community ID when available.
string
Confirmed community name when available.
string
Compatibility result ID.
object
Media details when used.
object
Structured recovery context.
boolean
Whether status is
success.Last modified on July 21, 2026
Send DM