Skip to main content
This guide walks you through sending Direct Messages and creating group conversations.
PrerequisitesBefore you begin, you’ll need:
  • A developer account with an approved App
  • User Access Token (OAuth 2.0 PKCE with dm.write and dm.read scopes)

Send a one-to-one message

1

Get the recipient's user ID

You need the user ID of the person you want to message. You can get this from the User lookup endpoint.
2

Send the message

cURL
curl -X POST "https://api.x.com/2/dm_conversations/with/9876543210/messages" \
  -H "Authorization: Bearer $USER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello! This is a message from the API."}'
3

Review the response

{
  "data": {
    "dm_conversation_id": "1234567890-9876543210",
    "dm_event_id": "1582103724607971332"
  }
}

Create a group conversation

1

Define participants

Gather the user IDs of everyone you want in the group (excluding yourself).
2

Create the group with first message

cURL
curl -X POST "https://api.x.com/2/dm_conversations" \
  -H "Authorization: Bearer $USER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "conversation_type": "Group",
    "participant_ids": ["944480690", "906948460078698496"],
    "message": {"text": "Welcome to our new group!"}
  }'
3

Receive the conversation ID

{
  "data": {
    "dm_conversation_id": "1582103724607971328",
    "dm_event_id": "1582103724607971332"
  }
}
Save the dm_conversation_id to add more messages later.

Add a message to an existing conversation

Send a message to a conversation you’re already part of:
cURL
curl -X POST "https://api.x.com/2/dm_conversations/1582103724607971328/messages" \
  -H "Authorization: Bearer $USER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text": "Adding another message to the conversation."}'

Send a message with media

1

Upload the media

First, upload your media using the Media Upload endpoint.
2

Send with media attachment

cURL
curl -X POST "https://api.x.com/2/dm_conversations/with/9876543210/messages" \
  -H "Authorization: Bearer $USER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Check out this image!",
    "attachments": [{"media_id": "1234567890123456789"}]
  }'

Delete a message

Delete a message you sent:
cURL
curl -X DELETE "https://api.x.com/2/dm_events/1582103724607971332" \
  -H "Authorization: Bearer $USER_ACCESS_TOKEN"
Response:
{
  "data": {
    "deleted": true
  }
}
You can only delete messages you sent, not messages from other participants.

Required scopes

When using OAuth 2.0 PKCE, your access token must have these scopes:
ScopeDescription
dm.writeSend and delete messages
dm.readRead conversations (required with dm.write)
tweet.readRequired for some expansions
users.readRequired for user expansions

Next steps

DM lookup

Retrieve DM conversations

Integration guide

Key concepts and best practices

API Reference

Full endpoint documentation

Sample code

Working code examples