Parameters
3 query
Query parameters
· 3issueKeystringRequiredIssue key.
PROJ-123pagenumberOptionalPage number.
11limitnumberOptionalItems per page.
100100Returns a paginated list of comments for a specific issue, ordered by creation date (oldest first).
3 query
issueKeystringRequiredIssue key.
PROJ-123pagenumberOptionalPage number.
11limitnumberOptionalItems per page.
1001001 status code documented
itemsobject[]RequiredidstringRequiredComment ID (format: "PROJ-123_c456").
authorIdnumberRequiredAuthor contact ID (FK; not necessarily who the UI shows for ai/system).
authorKind"human" | "ai" | "system"RequiredWho wrote the comment. human = staff / reporter, ai = AI Agent (authorName is rewritten server-side to "AI Agent" and authorEmail is empty), system = workflow / audit.
channel"internal" | "email_out" | "email_in"RequiredTimeline channel: internal = staff-only note (no e-mail was sent), email_out = comment sent to the customer as an e-mail, email_in = inbound customer reply lifted from an e-mail or the public support portal.
authorNamestringRequiredReady-to-render display name. For ai/system this is a synthetic label ("AI Agent" / "System"), NOT the FK contact's name.
authorEmailstringRequiredAuthor email — empty string for ai/system comments.
messagestringRequiredComment text.
insertedDateDate | string | string | numberRequiredWhen the comment was created.
When the comment was created.
updatedDateDate | string | string | numberRequiredLast update.
Last update.
isSpambooleanRequiredTrue when the LLM classifier flagged this comment as spam at insert time. Populated on public-portal replies (channel = email_in) — inbound e-mails, staff notes, and AI/system entries always report false.
spamReasonstring | nullRequiredShort human-readable reason from the classifier (≤200 chars). Null for non-spam rows or when the classifier declined to explain. Render as the tooltip on the spam badge — never surface to the customer.
avatarUrlstringOptionalUploaded avatar URL for human authors, resolved via the canonical contact-first / user-canonical fallback. Absent for ai/system rows (the admin renders their dedicated icon) and for human authors without an uploaded blob (the UI falls back to name initials).
geoIpnull | objectRequiredGeo snapshot of the caller that produced this comment. Populated for every writer that has request context: admin BFF (add-comment / add-email / promote-comment-to-email), public support portal (apiSupport /issue/:externalId/comment), and inbound mail with a parseable sender-IP header (X-Originating-IP / first Received: hop). Null for AI/system writers, historical rows written before the wiring, and loopback traffic. Rendered as a single-line strip in the admin timeline — never surfaced to the customer.
ipstringRequiredAccepted formats:
1.1.1.1 (4 octets, 0–255, no leading zeros).2001:0db8:0000:0000:0000:0000:0000:0001, zero-compressed 2001:db8::1, IPv4-mapped ::ffff:1.2.3.4, or scoped literals. Both upper- and lower-case hex are accepted.Server-side canonicalization (ipNormalize in core/src/lib/network/ipNormalize.ts):
::ffff:X.X.X.X is unwrapped to plain IPv4 (RFC 4291 §2.5.5.2) so 1.2.3.4 and ::ffff:1.2.3.4 share one brj__geo_ip row.::1, 0.0.0.0, localhost, empty string) collapse to 127.0.0.1.127.0.0.1 (loopback).On the wire: every response returns the canonicalized form — clients can safely rely on lowercase IPv6 and the plain-IPv4 unwrap when de-duping or joining. Server-originated writers (activity log, session log, ban list) resolve the visitor IP via resolveClientIp / resolveClientIpOrNull — always native IPv6 on Vercel Edge (there is no auto-mapping to ::ffff:X.X.X.X).
Enrichment: the system resolves reverse DNS, geolocation, ASN, mobile/proxy/hosting/Tor flags via our VikiTron GEO/IP resolver for both address families. Learn more
1.1.1.12001:4860:4860::8888citystring | nullRequiredcountrystring | nullRequiredcountryRegionstring | nullRequiredhostnamestring | nullRequireditemCountnumberRequiredTotal comment count.
{
"items": [
{
"id": "example_id",
"authorId": 0,
"authorName": "example_authorName",
"authorEmail": "example_authorEmail",
"message": "example_message",
"isSpam": false,
"avatarUrl": "example_avatarUrl"
}
],
"itemCount": 0
}GET /bff/issue/comments
curl -X GET "https://api.bizkithub.com/bff/issue/comments?issueKey=PROJ-123&page=1&limit=100" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY"All BizKitHub public API endpoints require authentication via API key.