Comments
Records in InfoLobby can have threaded comments. The API lets you read and post comments programmatically.
Fetch comments for a record
GET /api/table/<table_id>/record/<record_id>/comments/get
Optional parameters
Send these in the JSON request body, not the query string — ?limit=2 is ignored
(see Requests).
limit(default 20, clamped to 100)offset(default 0)
curl -X POST https://infolobby.com/api/table/101/record/42/comments/get \
-H "Authorization: Bearer il_live_..." \
-H "Content-Type: application/json" \
-d '{"limit": 50, "offset": 0}'
Comments are returned most-recent-first by page: offset=0 returns the newest
limit comments, and each page is ordered oldest→newest within itself. Increase
offset to page backward through older comments.
Response
[
{
"id": 7,
"table_id": 101,
"record_id": 42,
"user_id": 5,
"user_name": "Jane Doe",
"api_key_id": null,
"content": "Followed up by email",
"attachments": [
{
"name": "invoice.pdf",
"path": "/folder/12-101-invoice.pdf",
"type": "application/pdf",
"size": 18324,
"host": "..."
}
],
"created_at": "2026-04-12 14:32:01",
"updated_at": null
}
]
Post a comment
POST /api/table/<table_id>/record/<record_id>/comments/create
Request body
{
"content": "Synced from CRM",
"attachments": [],
"silent": true
}
content may be empty when at least one attachment is provided. Each attachment must be an object obtained from the upload endpoint described below. Paths from other tables, unsafe paths, and files over 50 MB are rejected.
Posting a comment follows the record, so the author is notified of later replies. That applies to personal API keys (they act as you) but not to account-level keys, which are treated as integrations and never follow on the owner's behalf.
silent (optional) posts the comment without notifying the record's followers. Anyone you @mention in content is still notified, and the comment still appears on the record for everyone. Use it for machine-written notes (sync logs, status stamps) that should not ping a whole team. See Silent writes.
Create an email comment
Drop an inbound email onto a record so that it appears in the timeline as a received email your users can reply to — just like a real email reply thread. Use this to bridge an external mailbox or another system's messages into InfoLobby.
POST /api/table/<table_id>/record/<record_id>/comments/createEmailComment
Request body
{
"from": { "name": "Jane Buyer", "email": "jane@customer.com" },
"to": ["sales@yourcompany.com"],
"subject": "Question about pricing",
"body": "<p>Hi, can you send a quote?</p>",
"attachments": [],
"messageId": "optional-rfc822-id",
"inReplyTo": "optional-rfc822-id"
}
from.emailis required and must be a valid address;from.nameis optional.tois an array of recipient addresses (optional but recommended).- One of
subject/bodymust be non-empty.bodyis HTML. attachmentsfollow the same upload + metadata flow as regular comments.messageId/inReplyToare optional RFC822 ids for threading;messageIdis generated if omitted.
The comment is created with type email_in and status received. A user replying to it from InfoLobby sends through their normal compose flow (subject to the table's allowed SMTP integrations). When the workspace has file storage, a full-message .eml is archived so the raw download and HTML view both work. Authorship rules for API keys are the same as for comments/create (user_id 0, api_key_id recorded; the display name is Email: <from>).
Read an email's HTML body
Comments of type email_out and email_in store a flattened plaintext snippet in content, which drops formatting and link destinations. This endpoint returns the message's own rich body instead.
GET /api/table/<table_id>/record/<record_id>/comment/<comment_id>/body_html
Response
{
"html": "<p>Hi,</p><p><a href=\"https://example.com/quote\">Open your quote</a></p>",
"format": "html",
"source": "eml"
}
formatishtmlwhen the message had an HTML part, ortextwhen it did not. Treat atextresponse as plain text, not markup.sourcetells you where the body came from:metadata(kept on the comment),eml(recovered from the archived full message), orsnippet(no archive available, so the flattened text is all there is).
The body is returned exactly as it arrived, with no sanitizing. It is third-party email markup, so render it in a sandboxed frame rather than inserting it into your own page. Requests for a comment that is not an email return an error.
Attach files to a comment
Files are uploaded first, then their metadata is included in the attachments array on comments/create. The workspace must have file storage configured.
POST /api/table/<table_id>/record/<record_id>/comments/upload
Request body
{
"name": "invoice.pdf",
"type": "application/pdf",
"data": "<base64-encoded bytes>"
}
50 MB per file. The response is the metadata object to splice into attachments:
{
"name": "invoice.pdf",
"path": "/folder/12-101-invoice.pdf",
"type": "application/pdf",
"size": 18324,
"host": "..."
}
When a record, table, or comment is deleted, attached files are queued for the same delayed cleanup as record file fields.
Mentions
You can @-mention a workspace member by embedding a token in content:
@{<user_id>:<display_name>}
For example: "Quick check @{42:Jane Doe} — can you confirm?". The token is stored verbatim in content; the InfoLobby UI renders it as a pill. When the comment is created (or edited to add a new mention) the targeted user receives a comment.mention notification and is auto-subscribed to the record. Only current workspace members are valid — unknown ids are silently ignored. The display-name half of the token is a snapshot at write time and does not auto-update if the user is later renamed; the user-id half is canonical.
Authorship when posted via API
When a comment is created with an API key:
user_idis stored as0user_nameis stored as"API: <key name>"(where<key name>is the name you chose when creating the key)api_key_idrecords the originating key for full traceability
This makes API-created comments visually distinguishable in the InfoLobby UI and fully auditable in the events table.
Example
curl -X POST https://infolobby.com/api/table/101/record/42/comments/create \
-H "Authorization: Bearer il_live_..." \
-H "Content-Type: application/json" \
-d '{"content":"Synced from CRM"}'