API REFERENCE
Get comments
On this page
/api/commentsRead existing stored comments on posts linked to a creator the caller can access. Authenticate with exactly one x-api-key or Authorization: Bearer credential. Caller identity comes from authentication; artist_account_id is the required target creator UUID (the retained wire name), not a caller override. account_id and other unknown or repeated query parameters return 400.
Access uses direct roster, shared-organization and Recoup-administrator checks, plus endpoint-local self-creator and owning-organization-key reads. These read rules do not grant artist mutation permission. Missing and denied targets both return 403. Access is checked on each request; this is not an atomic guarantee against revocation during an executing request. Ownership follows the creator’s linked socials through the post, not the commenter’s social_id. Optional post_id is a stored posts.id UUID, never a URL, and only narrows the authorized linked-post set. An unrelated post or no linked socials returns an empty page; neither permits an unscoped read.
page defaults to 1 and limit to 10; omitted or empty values use these defaults. Both otherwise require positive integers. Larger positive limits are accepted and clamped to 100; pagination.limit reports the effective value. Requests must satisfy page × effective_limit <= 2147483647 or return 400. Comments are ordered by commented_at descending, then id descending. Counts use the same ownership/post filter. Offset pages are deterministic for a fixed dataset, not a frozen snapshot during concurrent changes. A page beyond the results can be empty while retaining a nonzero exact total; no results means total_pages=0. A missing exact count is a 500, not an invented zero.
Each result has only id, post_id, social_id, comment and commented_at. Saved nulls are preserved in the nullable fields; a missing comment author/text is not invented. The stored post join determines inclusion; nullable post_id describes the retained row projection, not permission to read unlinked rows. No joined profile, account or grant metadata is returned. GET success and errors use Cache-Control: private, no-store. Authentication failures are 401; lookup failures are a masked 500 with no unscoped/provider fallback.
This reads saved evidence and does not start scraping, enrichment, billing or comment-writing work. The existing link lookup reads at most 10,000 social links; stored reads do not establish complete ingestion/history, a live report, or the original customer weekly-report journey. The implementation is merged in API #1062; hosted/customer verification remains separate in Mono #327/app #2023.
Authentication
x-api-key in header
bearerAuth bearer
Request
curl --request GET \
--url 'https://api.recoupable.dev/api/comments?artist_account_id=11111111-1111-4111-8111-111111111111' \
--header 'x-api-key: YOUR_API_KEY'Replace the YOUR_ placeholders with your values. Required query parameters are included; optional parameters are listed below.
Try it
Fill in the fields, send the request from your browser, and read the live response. The curl below updates as you type.
Kept in this browser tab only and cleared when it closes.
curl --request GET \
--url 'https://api.recoupable.dev/api/comments'Parameters
Query parameters
artist_account_idstringrequiredRequired target creator account UUID, using the retained artist wire name. It never overrides the authenticated caller.
post_idstringOptional stored posts.id UUID. Narrows the authorized linked-post set; an unrelated stored post returns an empty page. This is not a post URL.
pageintegerPositive integer page, default 1 for omitted or empty values. page × effective_limit must not exceed 2147483647.
Default: 1
limitintegerPositive requested page size, default 10 for omitted or empty values. Values above 100 are accepted and clamped to 100; the response reports the effective size.
Default: 10
Responses
200Stored comments and exact scoped pagination+
Cache-Controlresponse headerAll GET success and error responses disable shared caching.
application/json
statusstring · enumrequiredStatus of the request
Values: "success"
commentsarray<Comment>requiredSaved comments within the authorized creator’s linked-post set and optional post UUID filter.
Item properties for comments
idstringrequiredUUID of the comment
format: uuid
post_idstring | nullrequiredStored post UUID when present. Saved nullable row shape is retained; ownership is still enforced through the linked post join.
format: uuid
social_idstring | nullrequiredStored commenter social UUID, or null when absent. This is not the creator ownership filter.
format: uuid
commentstring | nullrequiredSaved comment text, or null when unavailable; no text is synthesized.
commented_atstringrequiredTimestamp with timezone of when the comment was made
format: date-time
paginationobjectrequiredPagination metadata for the response
Properties for pagination
total_countintegerrequiredExact total within the same authorized linked-post and optional post filter.
minimum: 0
pageintegerrequiredCurrent page number
minimum: 1
limitintegerrequiredEffective page size after clamping to 100.
minimum: 1 · maximum: 100
total_pagesintegerrequiredCeiling of total_count/effective limit; zero when total_count is zero.
minimum: 0
400Invalid, repeated, unknown or unsupported-offset query parameters+
Cache-Controlresponse headerAll GET success and error responses disable shared caching.
application/json
statusstring · enumrequiredValues: "error"
errorstringrequiredmissing_fieldsarray<string>requiredValidation path, possibly empty for unknown query keys.
Item properties for missing_fields
string
401Missing/conflicting credentials or rejected authentication; existing error or message envelope+
Cache-Controlresponse headerAll GET success and error responses disable shared caching.
application/json
anyOf · object 1
statusstring · enumrequiredAlways error.
Values: "error"
errorstringrequiredHuman-readable error message or documented error code.
Additional properties
any
anyOf · object 2
statusstring · enumrequiredAlways error.
Values: "error"
messagestringrequiredHuman-readable authentication error message.
Additional properties
any
403Target is missing or not accessible; both use the same denial+
Cache-Controlresponse headerAll GET success and error responses disable shared caching.
application/json
statusstring · enumrequiredAlways error.
Values: "error"
errorstringrequiredHuman-readable error message or documented error code.
Additional properties
any
500Masked lookup/count failure; no unscoped or provider fallback+
Cache-Controlresponse headerAll GET success and error responses disable shared caching.
application/json
statusstring · enumrequiredAlways error.
Values: "error"
errorstringrequiredHuman-readable error message or documented error code.
Additional properties
any
Full specification
Download the OpenAPI file for complete schemas, constraints, and examples.
Download social.jsonView operation source
{
"operationId": "getComments",
"description": "Read existing stored comments on posts linked to a creator the caller can access. Authenticate with exactly one x-api-key or Authorization: Bearer credential. Caller identity comes from authentication; artist_account_id is the required target creator UUID (the retained wire name), not a caller override. account_id and other unknown or repeated query parameters return 400.\n\nAccess uses direct roster, shared-organization and Recoup-administrator checks, plus endpoint-local self-creator and owning-organization-key reads. These read rules do not grant artist mutation permission. Missing and denied targets both return 403. Access is checked on each request; this is not an atomic guarantee against revocation during an executing request. Ownership follows the creator’s linked socials through the post, not the commenter’s social_id. Optional post_id is a stored posts.id UUID, never a URL, and only narrows the authorized linked-post set. An unrelated post or no linked socials returns an empty page; neither permits an unscoped read.\n\npage defaults to 1 and limit to 10; omitted or empty values use these defaults. Both otherwise require positive integers. Larger positive limits are accepted and clamped to 100; pagination.limit reports the effective value. Requests must satisfy page × effective_limit <= 2147483647 or return 400. Comments are ordered by commented_at descending, then id descending. Counts use the same ownership/post filter. Offset pages are deterministic for a fixed dataset, not a frozen snapshot during concurrent changes. A page beyond the results can be empty while retaining a nonzero exact total; no results means total_pages=0. A missing exact count is a 500, not an invented zero.\n\nEach result has only id, post_id, social_id, comment and commented_at. Saved nulls are preserved in the nullable fields; a missing comment author/text is not invented. The stored post join determines inclusion; nullable post_id describes the retained row projection, not permission to read unlinked rows. No joined profile, account or grant metadata is returned. GET success and errors use Cache-Control: private, no-store. Authentication failures are 401; lookup failures are a masked 500 with no unscoped/provider fallback.\n\nThis reads saved evidence and does not start scraping, enrichment, billing or comment-writing work. The existing link lookup reads at most 10,000 social links; stored reads do not establish complete ingestion/history, a live report, or the original customer weekly-report journey. The implementation is merged in API #1062; hosted/customer verification remains separate in Mono #327/app #2023.",
"parameters": [
{
"name": "artist_account_id",
"in": "query",
"description": "Required target creator account UUID, using the retained artist wire name. It never overrides the authenticated caller.",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"example": "11111111-1111-4111-8111-111111111111"
},
{
"name": "post_id",
"in": "query",
"description": "Optional stored posts.id UUID. Narrows the authorized linked-post set; an unrelated stored post returns an empty page. This is not a post URL.",
"required": false,
"schema": {
"type": "string",
"format": "uuid"
},
"example": "22222222-2222-4222-8222-222222222222"
},
{
"name": "page",
"in": "query",
"description": "Positive integer page, default 1 for omitted or empty values. page × effective_limit must not exceed 2147483647.",
"required": false,
"schema": {
"type": "integer",
"minimum": 1,
"default": 1
},
"example": 1
},
{
"name": "limit",
"in": "query",
"description": "Positive requested page size, default 10 for omitted or empty values. Values above 100 are accepted and clamped to 100; the response reports the effective size.",
"required": false,
"schema": {
"type": "integer",
"minimum": 1,
"default": 10
},
"example": 10
}
],
"responses": {
"200": {
"description": "Stored comments and exact scoped pagination",
"headers": {
"Cache-Control": {
"description": "All GET success and error responses disable shared caching.",
"schema": {
"type": "string",
"const": "private, no-store"
},
"example": "private, no-store"
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CommentsResponse"
}
}
}
},
"400": {
"description": "Invalid, repeated, unknown or unsupported-offset query parameters",
"headers": {
"Cache-Control": {
"description": "All GET success and error responses disable shared caching.",
"schema": {
"type": "string",
"const": "private, no-store"
},
"example": "private, no-store"
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CommentsValidationErrorResponse"
}
}
}
},
"401": {
"description": "Missing/conflicting credentials or rejected authentication; existing error or message envelope",
"headers": {
"Cache-Control": {
"description": "All GET success and error responses disable shared caching.",
"schema": {
"type": "string",
"const": "private, no-store"
},
"example": "private, no-store"
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CommentsAuthenticationErrorResponse"
}
}
}
},
"403": {
"description": "Target is missing or not accessible; both use the same denial",
"headers": {
"Cache-Control": {
"description": "All GET success and error responses disable shared caching.",
"schema": {
"type": "string",
"const": "private, no-store"
},
"example": "private, no-store"
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CommentsErrorResponse"
}
}
}
},
"500": {
"description": "Masked lookup/count failure; no unscoped or provider fallback",
"headers": {
"Cache-Control": {
"description": "All GET success and error responses disable shared caching.",
"schema": {
"type": "string",
"const": "private, no-store"
},
"example": "private, no-store"
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CommentsErrorResponse"
}
}
}
}
},
"summary": "Read saved comments on an authorized creator’s linked posts",
"security": [
{
"apiKeyAuth": []
},
{
"bearerAuth": []
}
]
}