Direct messaging is available exclusively through the JxInsta Mobile client. The Inbox class represents the authenticated account’s DM inbox and holds a list of Thread objects. Each Thread maps to a single conversation and exposes methods for sending messages, paginating history, marking the thread as seen, and deleting it.
The Web client (com.jxinsta.web) does not support direct messages. All code examples on this page use the Mobile client (com.jxinsta.mobile).
Fetching the inbox
Call getDirectInbox() on an authenticated Mobile JxInsta instance. The two integer parameters control how many threads and messages per thread are loaded in the initial fetch.
JxInsta insta = new JxInsta("your_username", "your_password");
// Load up to 20 threads, with up to 10 messages each
Inbox inbox = insta.getDirectInbox(20, 10);
The returned Inbox exposes:
| Field | Type | Description |
|---|
totalThreads | int | Number of threads returned in this fetch. |
threads | List<Thread> | The list of conversation threads. |
users | List<String> | Usernames of all participants across all fetched threads. |
Each Thread in inbox.threads carries the following fields:
| Field | Type | Description |
|---|
id | String | The unique thread ID. |
recipient | String | Username of the other participant. |
recipientId | long | Numeric user ID of the other participant. |
displayPicture | String | URL of the recipient’s profile picture (HD version). |
messages | List<String> | The pre-loaded message texts from the initial inbox fetch. |
oldestCursor | String | Pagination cursor used to load earlier messages. |
lastItemId | String | ID of the most recent item, used by markSeen(). |
for (Thread thread : inbox.threads) {
System.out.println("Conversation with: " + thread.recipient);
System.out.println("Thread ID: " + thread.id);
System.out.println("Display picture: " + thread.displayPicture);
for (String text : thread.messages) {
System.out.println(" > " + text);
}
}
Fetching a single thread
Use inbox.getThread() to load a specific conversation by its ID with a controlled message limit.
Thread thread = inbox.getThread("340282366841710300949128148537179982649", 20);
Sending a text message
Call sendMessage() on a Thread instance with the message text.
Thread thread = inbox.threads.get(0);
thread.sendMessage("Hey, saw your post — looks great!");
sendMessage() throws InstagramException if the request fails.
Sending an image
sendImage() uploads an image from an InputStream and sends it to the thread. The second argument is an optional caption that accompanies the image.
InputStream image = new FileInputStream("/path/to/photo.jpg");
thread.sendImage(image, "Check this out!");
The image must be a JPEG. Passing a non-JPEG stream will result in an InstagramException with an IO reason code.
Paginating message history
The initial inbox fetch only loads the most recent messages. To load older messages, call getMessages() on the thread to obtain a MessagePaginator.
MessagePaginator implements Iterator<List<Message>> and fetches 20 messages per page in reverse chronological order (oldest first within each page, pages moving backward in time).
MessagePaginator history = thread.getMessages();
while (history.hasNext()) {
List<Message> page = history.next();
for (Message message : page) {
System.out.println("[" + message.type + "] " + message.text);
}
}
Message fields
Each Message object contains:
| Field | Type | Description |
|---|
text | String | The message text (populated for TEXT type messages). |
mediaURL | String | URL to the image or video (populated for IMAGE and VIDEO types). |
postURL | String | URL to a shared post’s thumbnail (populated for POST type). |
type | TYPE | The message type: TEXT, IMAGE, VIDEO, POST, or UNDEFINED. |
isSent | boolean | true if the message was sent by the authenticated account. |
isReply | boolean | true if this message is a reply to another message. |
replyOf | Message | The message being replied to, if isReply is true. |
for (Message message : page) {
if (message.type == Message.TYPE.TEXT) {
String direction = message.isSent ? "Sent" : "Received";
System.out.println(direction + ": " + message.text);
} else if (message.type == Message.TYPE.IMAGE) {
System.out.println("Image: " + message.mediaURL);
} else if (message.type == Message.TYPE.POST) {
System.out.println("Shared post thumbnail: " + message.postURL);
}
if (message.isReply && message.replyOf != null) {
System.out.println(" In reply to: " + message.replyOf.text);
}
}
Marking a thread as seen
markSeen() marks the most recent message in the thread as read using the stored lastItemId.
If lastItemId is null (for example, if the thread was constructed without loading items), markSeen() is a no-op.
Deleting a thread
delete() permanently removes the thread from the authenticated account’s inbox.
Deleting a thread cannot be undone. The conversation is removed only from your side — the other participant’s copy is not affected.
Fetching message requests
Unaccepted DM requests are stored separately from the main inbox. Use inbox.getRequests() to load them.
List<Thread> requests = inbox.getRequests(10, 5);
for (Thread request : requests) {
System.out.println("Message request from: " + request.recipient);
}
The parameters mirror getDirectInbox(): the first is the maximum number of request threads to return, the second is the maximum messages per thread.
Full inbox workflow example
Authenticate and fetch the inbox
JxInsta insta = new JxInsta("your_username", "your_password");
Inbox inbox = insta.getDirectInbox(10, 5);
Find a thread by recipient username
Thread target = null;
for (Thread thread : inbox.threads) {
if ("alice".equals(thread.recipient)) {
target = thread;
break;
}
}
Send a reply and mark the thread seen
if (target != null) {
target.sendMessage("On my way!");
target.markSeen();
}
Page through the full message history
if (target != null) {
MessagePaginator history = target.getMessages();
while (history.hasNext()) {
for (Message msg : history.next()) {
System.out.println(msg.isSent ? "Me: " : "Them: " + msg.text);
}
}
}