Explain and use the Inline CLI (inline) for authentication, chats, users, spaces, messages, search, attachments, downloads, JSON output, and configuration...
--json: Output command JSON to stdout; existing RPC fields are preserved with command-specific metadata.--json is set and a command fails, the CLI prints a structured error JSON to stderr and exits non-zero. Common fields are code, message, status, apiError, apiErrorCode, body, hint, and examples.--json mode. Specifically: inline users list --ids/--id, inline bots list --ids/--id, and inline chats list --ids/--id.inline chats list --json supports --filter, --limit, and --offset for pre-filtered/paginated payloads. inline users list --json --filter ... and inline bots list --json --filter ... also return pre-filtered payloads.--json mode; pass --yes/-y explicitly.--pretty: Pretty-print JSON output (default).--compact: Compact JSON output (no whitespace).--json --compact for pipelines and agent parsing.COLUMNS environment variable. Set COLUMNS=120 before a command to allow wider previews, or a smaller value to force denser truncation.inline chats list gives chat titles extra room and wraps long titles onto a second table row before truncating, so prefer the normal table before falling back to JSON for title disambiguation.Error, Code, and any available status/API error/body preview/hint/examples.NO_COLOR=1 to disable it, or CLICOLOR_FORCE=1 to force it in a non-TTY.inline login [--email you@x.com | --phone +15551234567]inline auth login.inline login --email you@x.com --send-code --json --compactinline login --email you@x.com --code 123456 --json --compact--challenge-token.--code-stdin instead of --code to read the code from piped stdin.inline login --phone +15551234567 --send-code --json --compact--phone and --code/--code-stdin.INLINE_TOKEN=... inline me --jsoninline meinline auth me.inline logoutinline auth logout.INLINE_TOKEN is set, the CLI remains authenticated from the environment; JSON output reports this as effectiveTokenSource: "INLINE_TOKEN".inline skill install$CODEX_HOME/skills/inline or ~/.codex/skills/inline.--force; extra files are preserved.npx skills add https://github.com/inline-chat/inline/tree/main/skills/inline --global --yes.inline me and inline whoamiinline auth me.inline logininline auth login.inline logoutinline auth logout.inline search ...inline messages search ....--translate.inline transcript ...inline messages transcript ....inline transcript --chat-id ID --limit 500 --download-media --output ./transcript-bundle so the CLI writes transcript.md plus local media links in media/.inline chat ..., inline thread ..., inline threads ...inline chats ....inline bot ...inline bots ....inline chats listinline chats list --json --filter "launch"GetChatsResult JSON payload, but pre-filtered by chat name/space/id for agent pipelines.inline chats get [--chat-id 123 | --user-id 42]inline chats participants --chat-id 123inline chats add-participant --chat-id 123 --user-id 42inline chats remove-participant --chat-id 123 --user-id 42inline chats create --title "Project" [--space-id 31] [--description "Spec"] [--emoji ":rocket:"] [--public] [--participant 42]--public is set, participants must be empty.inline chats create-dm --user-id 42inline chats update-visibility --chat-id 123 [--public | --private --participant 42 --participant 99]--public cannot include participants.--private requires one or more --participant values.inline chats rename --chat-id 123 --title "New title" [--emoji "π"]inline chats mark-unread [--chat-id 123 | --user-id 42]inline chats mark-read [--chat-id 123 | --user-id 42] [--max-id 456]--max-id is omitted, marks through the latest message.inline chats delete --chat-id 123--yes/-y is provided (--json requires --yes/-y).inline bot ... maps to inline bots ....inline bots list [--filter "name"] [--ids | --id]--filter works in table and JSON modes. --ids/--id are table-only line-output helpers.inline bots create --name "Build Bot" --username build_bot [--add-to-space 31]inline bots reveal-token explicitly. JSON includes the token.inline bots reveal-token --bot-user-id 42inline typing start [--chat-id 123 | --user-id 42]inline typing stop [--chat-id 123 | --user-id 42]inline users list [--filter "name"] [--ids | --id]--filter matches name, username, email, or phone in table and JSON modes.--ids prints one user id per line.--id requires exactly one match and prints that id.--ids/--id are table-only line-output helpers.inline users get --id 42inline spaces listinline spaces members --space-id 31inline spaces invite --space-id 31 [--user-id 42 | --email you@x.com | --phone +15551234567] [--admin] [--public-chats]inline spaces delete-member --space-id 31 --user-id 42--yes/-y to skip; --json requires --yes/-y).inline spaces update-member-access --space-id 31 --user-id 42 [--admin | --member] [--public-chats]--admin or --member (and optional --public-chats).inline notifications getinline notifications set [--mode all|none|mentions|only-mentions] [--silent | --sound]inline updateinline doctor--json includes client identity diagnostics: client type/version, user-agent, OS version, device name, and metadata header names sent to the server.inline tasks create-linear --chat-id 123 --message-id 456 [--space-id 31]inline tasks create-notion --chat-id 123 --message-id 456 --space-id 31inline schema protoinline messages list [--chat-id 123 | --user-id 42] [--limit 50] [--offset-id 456] [--has-media] [--empty-text] [--forwarded] [--translate en] [--since "yesterday"] [--until "today"]--sender-id USER_ID filters authors, independently of the DM target. Time/sender/content filters apply to the fetched page; JSON page.nextOffsetId continues even an empty filtered result. Named days use UTC.--has-media, --empty-text, and --forwarded can be combined and work in table or JSON mode.--translate <lang> fetches translations and includes them in output.inline messages transcript [--chat-id 123 | --user-id 42] [--limit 500] [--offset-id 456 | --from-msg-id 456 | --message-id SELECTOR ...] [--output PATH]inline transcript ....MSG comments.--download-media [--media-dir DIR] [--parallel N] to download photos/files in one pass and rewrite transcript links to local paths.--output is a directory, or a no-extension path with --download-media, transcript writes transcript.md and uses media/ inside that directory.inline messages export [--chat-id 123 | --user-id 42] [--limit 50] [--offset-id 456 | --from-msg-id 456 | --message-id SELECTOR ...] [--format json|jsonl|markdown|csv] [--since "1w ago"] [--until "today"] [--output PATH]--output is omitted, payload content prints to stdout.--download-media [--media-dir DIR] [--parallel N] to populate media localPath values; markdown and CSV include those local paths.--output is a directory, or a no-extension path with --download-media, export writes transcript.<format> there and defaults media to media/.users, chats, and spaces records so agents do not need jq joins for common sender/source names.inline messages search [--chat-id 123 | --user-id 42] --query "onboarding" [--query "alpha beta"] [--limit 50] [--translate en] [--since "today"] [--until "tomorrow"]--query is repeatable; each query can contain space-separated terms (ANDed within a query, ORed across queries). Extra whitespace is collapsed.--since and --until accept relative time expressions like yesterday, 2h ago, monday, 2024-01-15, or RFC3339.--translate, JSON output keeps raw search fields and adds a top-level translations array; table output includes translated previews.inline messages get [--chat-id 123 | --user-id 42] --message-id SELECTOR [--message-id SELECTOR ...] [--translate en]456), comma lists (91,92,100), ranges (91-100), and repeated flags.messages and any missingMessageIds.inline messages send [--chat-id 123 | --user-id 42] [--text "hi" | --message "hi" | --msg "hi" | -m "hi"] [--stdin | --text-file PATH] [--reply-to 456] [--mention USER_ID:OFFSET:LENGTH ...] [--attach PATH ...] [--force-file]**bold**, *italic*, <u>underline</u>, ~~strikethrough~~, ==highlight==, inline backtick code, [label](https://example.com), [Name](inline://user?id=42), and [[Title]](inline://chat?id=123).# through ###### headings, - item / 1. item lists, - [ ] / - [x] checklists, > quotes, pipe tables with a header separator row, --- separators, triple-backtick/tilde code fences with an optional language, four-space indented code, and  images. Use blank lines between blocks; do not fence tables or the whole message.$x^2$ inline; $$ on separate lines around display TeX. Disclosures: <details open>, <summary>Title</summary>, body Markdown, </details> on separate lines (omit open to start collapsed). Use <summary kind="progress"> only while working. Footers: <footer>Metadata</footer> on its own line.--text-file report.md or --stdin for multiline content; whitespace is preserved. Single-quote shell text to protect backticks and dollar signs. Escape punctuation with a backslash for literal syntax. Footnotes and arbitrary HTML are unsupported; rich styles/blocks and math rendering depend on the recipient client.inline messages edit uses the same Markdown parsing contract. Mentions are provided via --mention with UTF-16 offsets; because those offsets address literal input, any send or caption with --mention preserves Markdown syntax instead of parsing it.--stdin reads message text from piped or redirected stdin; it fails fast if stdin is an interactive terminal.--attach is repeatable. Each attachment is sent as its own message; --text is reused as the caption.--force-file uploads photos/videos as files (documents).--mention is repeatable and must match the message text (user_id:offset:length with UTF-16 units).inline messages forward [--from-chat-id 123 | --from-user-id 42] --message-id 456 [--message-id 789] [--to-chat-id 321 | --to-user-id 84] [--no-header]--message-id to forward multiple messages.inline messages edit [--chat-id 123 | --user-id 42] --message-id 456 [--text "updated" | --message "updated" | --msg "updated" | -m "updated" | --stdin]--stdin expects piped or redirected stdin, not an interactive prompt.inline messages delete [--chat-id 123 | --user-id 42] --message-id 456 [--message-id 789]--yes/-y to skip; --json requires --yes/-y).inline messages add-reaction [--chat-id 123 | --user-id 42] --message-id 456 --emoji "π":shortcode:).inline messages delete-reaction [--chat-id 123 | --user-id 42] --message-id 456 --emoji "π":shortcode:).inline messages download [--chat-id 123 | --user-id 42] [--message-id SELECTOR ... | --from-msg-id 456 --limit 50] [--output PATH | --dir PATH] [--parallel 8]--output or --dir.--dir, use bounded concurrency, skip messages without media, and prefix filenames with date, MSG ID, media type, and media ID.--from-msg-id ID --limit N --dir DIR to download media from a contiguous history window without enumerating IDs.files, skippedMessageIds, missingMessageIds, and errors.inline login (prompts for email/phone + code, then prints welcome name)inline meinline logoutinline doctorinline chats listinline thread listinline chats update-visibility --chat-id 123 --publicinline chats update-visibility --chat-id 123 --private --participant 42 --participant 99inline messages search --chat-id 123 --query "design review"inline messages search --chat-id 123 --query "design review" --jsoninline messages search --chat-id 123 --query "diseΓ±o" --translate en --jsoninline search --chat-id 123 --query "design review"inline messages list --chat-id 123 --translate eninline messages list --chat-id 123 --since "yesterday"inline messages list --chat-id 123 --since "2h ago" --until "1h ago"inline transcript --chat-id 123 --limit 500 --download-media --output ./feedback-bundleinline transcript --chat-id 123 --from-msg-id 600 --limit 50 --download-media --output ./feedback-bundleinline transcript --chat-id 123 --limit 500 --download-media --media-dir ./feedback-media --output ./feedback.mdinline messages export --chat-id 123 --output ./messages.jsoninline messages export --chat-id 123 --format markdown --output ./messages.mdinline messages export --chat-id 123 --format csv --output ./messages.csvinline messages export --chat-id 123 --since "1w ago" --output ./recent.jsoninline messages send --chat-id 123 --text "FYI" --attach ./photo.jpg --attach ./spec.pdfinline messages send --chat-id 123 --reply-to 456 --text "on it"inline messages forward --from-chat-id 123 --message-id 456 --to-chat-id 789inline messages forward --from-user-id 42 --message-id 456 --to-user-id 84inline messages send --chat-id 123 --text "@Sam hello" --mention 42:0:4inline messages download --chat-id 123 --message-id 456 --dir ./downloadsinline messages download --chat-id 123 --message-id 80-100 --dir ./downloadsinline chats rename --chat-id 123 --title "New title"inline bots listinline bots create --name "Build Bot" --username build_botinline bots reveal-token --bot-user-id 42 (token is not printed by default)inline tasks create-linear --chat-id 123 --message-id 456inline tasks create-notion --chat-id 123 --message-id 456 --space-id 31inline typing start --chat-id 123inline typing stop --chat-id 123inline messages edit --chat-id 123 --message-id 456 --text "updated"inline messages delete --chat-id 123 --message-id 456inline spaces invite --space-id 31 --email you@example.cominline spaces update-member-access --space-id 31 --user-id 42 --admininline users list | grep -i "partial_name"
Faster than parsing JSON when you just need user ID.
# Find the DM user id by name/email/username
USER_ID="$(inline users list --filter "sam" --id)"
# Read the last 5 messages
inline messages list --user-id "$USER_ID" --limit 5 --json --compact
# Fetch exact messages once you know their IDs
inline messages get --user-id "$USER_ID" --message-id 91,92,100 --json
# Download several media messages at once
inline messages download --user-id "$USER_ID" --message-id 80-100 --dir ./downloads
inline messages get --chat-id ID --message-id 1
inline messages get --chat-id ID --message-id 1,2,4 --json
inline messages get --chat-id ID --message-id 10-20 --json
inline messages download --chat-id ID --message-id 10-20 --dir ./media --parallel 8
inline messages download --chat-id ID --from-msg-id 600 --limit 50 --dir ./media --parallel 8
inline messages search --user-id ID --query "bug" --query "issue" --query "loom" --query "broken" --limit 30 --json
Each --query is ORed together - useful for finding feedback items.
inline transcript --chat-id ID --limit 500 --download-media --output ./transcript-bundle when media might matter# Page back with offset-id
inline messages list --chat-id ID --limit 50 --offset-id 1234
# Get the latest message id from the first table row
inline messages list --chat-id ID --limit 1
# Export a batch for offline review
inline transcript --chat-id ID --limit 500 --download-media --output ./chat-bundle
inline transcript --chat-id ID --from-msg-id 600 --limit 50 --download-media --output ./chat-bundle
inline messages export --chat-id ID --limit 500 --output ./chat.json
# Fetch exact IDs in one request
inline messages get --chat-id ID --message-id 91,92,100 --json --compact
# Count fetched messages
inline messages list --chat-id ID --limit 500 --json --compact | jq '.messages | length'
# Extract media message IDs for custom workflows
inline messages list --chat-id ID --limit 500 --has-media --json --compact | jq -r '.messages[].id'
Chat list (GetChatsResult, truncated to essential fields):
{
"dialogs": [
{
"peer": { "type": { "Chat": { "chat_id": 340 } } },
"space_id": 31,
"archived": false,
"pinned": false,
"read_max_id": 1,
"unread_count": 0,
"chat_id": 340,
"unread_mark": false
}
],
"chats": [
{
"id": 340,
"title": "Main",
"space_id": 31,
"description": "Main chat for everyone in the space",
"emoji": null,
"is_public": true,
"last_msg_id": 1,
"peer_id": { "type": { "Chat": { "chat_id": 340 } } },
"date": 1754585453
}
],
"spaces": [
{ "id": 31, "name": "Design", "creator": false, "date": 1750000000 }
],
"users": [
{
"id": 1000,
"first_name": "Ava",
"last_name": "Chen",
"username": "ava",
"email": "ava@example.com",
"min": false,
"bot": false
}
],
"messages": [
{
"id": 1,
"from_id": 1000,
"peer_id": { "type": { "Chat": { "chat_id": 340 } } },
"chat_id": 340,
"message": null,
"out": true,
"date": 1754585453,
"media": {
"media": {
"Document": {
"document": {
"id": 32,
"file_name": "recording.mp4",
"mime_type": "video/mp4",
"size": 6932635,
"cdn_url": "https://..."
}
}
}
}
}
]
}
Message list (GetChatHistoryResult, truncated to essential fields):
{
"messages": [
{
"id": 456,
"from_id": 42,
"peer_id": { "type": { "Chat": { "chat_id": 123 } } },
"chat_id": 123,
"message": "Ship it",
"out": true,
"date": 1733184000,
"attachments": {
"attachments": [
{
"id": 9001,
"attachment": {
"UrlPreview": {
"id": 88,
"url": "https://...",
"site_name": "Docs",
"title": "Spec",
"description": "API rollout spec"
}
}
}
]
}
}
]
}
Use inline capabilities COMMAND... --compact to read the installed command metadata, conflicts, groups, and examples offline. Resolve the source conversation, chosen authors/messages, and destination independently; a person in βmy messages to Xβ can identify the source DM depending on the full request.
inline messages search --chat-id SOURCE --query 'TOPIC' --sender-id AUTHOR --limit 50 --json --compact
inline messages get --chat-id SOURCE --message-id 91,92,100 --json --compact
inline messages forward --from-chat-id SOURCE --to-chat-id DESTINATION --message-id 91,92,100 --json --receipt --compact
List/search JSON includes a page with raw fetched count, filtered returned count, and nextOffsetId; use that cursor with --offset-id even if local filters return zero matches. --compact changes whitespace, not which fields are included. User/space lookups retain protocol keys but clear all unrelated entity lists.
Batch --message-id selectors use IDs, comma lists, ascending ranges, or repeated flags, up to 1000 expanded IDs. Forwarding preserves input order and duplicates; read/export/download/delete selectors deduplicate IDs. Forward JSON preserves updates and adds ordered forwarded source/destination ID pairs; --receipt returns only the successful receipt. Failed forwarding can already have delivered messages; inspect before retrying. It does not preserve reactions or reply relationships.
Text inputs are exclusive: --text, --stdin, or --text-file PATH (use - for stdin). File/stdin input is bounded to 1 MiB, nonblank UTF-8, and preserves whitespace. --force-file requires attachments. Children inherit root-chat access plus their own direct/group grants; participants added only to an intermediate child are not automatically inherited by its descendants. Newly created private children include their creator directly. With chats subthread --message-id, an existing reply thread is reused without changing its title, description, emoji, or participants; creation inputs apply only to a new child and reuse does not repair older creator membership.