Messages

Messages

Post, list, reply to, react to, and cross-post messages. The feed combines public messages, your own messages, and messages from people you follow.

Endpoint table

MethodPathAuthDescription
GET/api/messagesSession or BearerList messages. Query: limit, offset, onlyMine (bool), tag (string).
GET/api/messages/searchSession or BearerSearch top-level messages by content (case-insensitive substring), scoped to your feed visibility. Query: q (required, 1–200 chars), limit (default 20, max 100), offset (default 0), onlyMine (bool, default false).
POST/api/messagesSession or BearerCreate a message (see body reference below). Returns 201.
GET/api/messages/:idSession or BearerGet one message by ID.
PATCH/api/messages/:idSessionUpdate a future-scheduled message (scheduledAt, scheduledCrossPostConfig).
DELETE/api/messages/:idSession or BearerDelete a message (own messages only). Cascades replies and blob media.
GET/api/messages/scheduledSession or BearerUpcoming scheduled messages. Query: rangetoday, week, or month (default month).
GET/api/messages/:id/repliesSessionReplies to a message.
POST/api/messages/:id/digSessionAdd an I Dig! reaction (idempotent). Returns { digCount, dugByMe }.
DELETE/api/messages/:id/digSessionRemove your dig.
POST/api/messages/:id/metadataPublicTriggers async link-metadata fetch for a message (used internally after creation).
POST/api/messages/images/uploadSession or BearerUpload an image for attachment. Subscriber only.
POST/api/messages/videos/uploadSession or BearerUpload a video for attachment. Subscriber only.

Listing messages

GET /api/messages?onlyMine=true&limit=2&offset=0
Authorization: Bearer il_tok_...
{
  "data": [
    {
      "id": "msg_001",
      "content": "Just shipped a new feature!",
      "publiclyVisible": true,
      "tags": ["dev", "release"],
      "digCount": 4,
      "dugByMe": false,
      "replyCount": 1,
      "createdAt": "2025-06-10T14:22:00.000Z",
      "author": { "id": "...", "username": "yourhandle", "displayName": "Your Name", "avatarUrl": null }
    }
  ],
  "pagination": { "total": 42, "limit": 2, "offset": 0, "hasMore": true }
}

Searching messages

GET /api/messages/search?q=feature&limit=20&onlyMine=false
Authorization: Bearer il_tok_...

Matching is a case-insensitive substring over message content, restricted to top-level messages (replies excluded) and scoped to your feed visibility (honors your viewingPreference). Each item uses the same message shape as GET /api/messages. The response wraps results in { "messages": [ ... ], "pagination": { "total", "limit", "offset", "hasMore" } }. An empty or over-200-character q, or a limit above 100, returns 400.

Creating a message

Body fields

FieldTypeDescription
contentstringRequired unless pushing with no comment. Max length from your account setting (default 666 chars).
publiclyVisiblebooleanDefaults to your account's default visibility.
parentIdstringReply to this message ID. Mutually exclusive with pushedMessageId.
pushedMessageIdstringRepost this public message ID. content may be empty (plain repost) or non-empty (repost with comment).
tagsstring[]Free-form string labels. Case-sensitive; lowercase recommended.
imageUrlsstring[]Up to 8 URLs from POST /api/messages/images/upload. Subscriber only.
videoUrlsstring[]1 URL from POST /api/messages/videos/upload. Subscriber only.
scheduledAtstring (ISO 8601)Future datetime to publish. Cannot combine with parentId or pushedMessageId. Subscriber only.
mastodonProviderIdsstring[]Linked Mastodon identity IDs (from GET /api/user/identities) to cross-post to. Subscriber only.
crossPostToBlueskybooleanCross-post to linked Bluesky account. Subscriber only.
crossPostToLinkedInbooleanCross-post to linked LinkedIn account. Subscriber only.
crossPostToTwitterbooleanCross-post to linked X (Twitter) account. Subscriber only.

Simple public message

POST /api/messages
Authorization: Bearer il_tok_...
Content-Type: application/json

{ "content": "Hello from the API!", "publiclyVisible": true, "tags": ["api"] }

Reply

POST /api/messages
Content-Type: application/json

{ "content": "Great point.", "publiclyVisible": true, "parentId": "msg_001" }

Scheduled cross-post (subscriber)

POST /api/messages
Content-Type: application/json

{
  "content": "Launching at 9 AM tomorrow!",
  "publiclyVisible": true,
  "scheduledAt": "2025-09-01T13:00:00.000Z",
  "crossPostToBluesky": true,
  "crossPostToTwitter": true,
  "mastodonProviderIds": ["clx9abc000002"]
}

Creation response

{
  "message": "Message created successfully",
  "data": { "id": "msg_003", "content": "...", "publiclyVisible": true, "createdAt": "..." }
}

For scheduled posts, scheduledAt is echoed back. For immediate cross-posts, a crossPostResults array is included with one entry per platform.

Uploading images and videos

Two-step flow — upload first, then reference the URL in imageUrls / videoUrls.

POST /api/messages/images/upload
Content-Type: multipart/form-data

file=<binary>

Response: { "url": "https://cdn.interlinedlist.com/images/abc123.webp" }

Image constraints: JPEG/PNG/WebP/GIF; auto-resized to 1200 px max side; ≤ 1.4 MB output.
Video constraints: MP4/WebM/QuickTime/AVI; max 3 MB; no server transcoding.

Cross-posting details

Cross-posting only works when the corresponding provider identity is linked to your account. See Authentication & OAuth for linking flows. For Mastodon, use the id of the identity from GET /api/user/identities (not the handle). LinkedIn additionally supports posting to organization pages — see LinkedIn Integration and Organizations.

Reactions and replies

POST /api/messages/msg_001/dig          # → { "digCount": 5, "dugByMe": true }
DELETE /api/messages/msg_001/dig        # → { "digCount": 4, "dugByMe": false }
GET /api/messages/msg_001/replies       # → array of reply messages