FastComments.com

The FastComments API

FastComments provides an API for searching and fetching data in your account.

In this documentation, you will find all supported resources by the API documented with their request and response types.

Authentication

The API is authenticated by passing your api key as either an API_KEY header or query parameter.

API Resources Internal Link

Resource Usage

It should be noted that fetching data from the API is counted as usage on your account.

Each resource will list what that usage is in its own section.

Some resources cost more to serve than others. Each endpoint has a set cost of credits per API call. For some endpoints, the number of credits varies based on the options and response sizes.

API usage can be checked on the Billing Analytics page and is updated every few minutes.

Note!

We suggest reading the Pages documentation first, to help limit confusion when determining what values to pass for urlId in the Comment API.

AuditLog Structure Internal Link

An AuditLog is an object that represents an audited event for tenants that have access to this feature.

The structure for the AuditLog object is as follows:

AuditLog Structure
Copy Copy
1
2interface AuditLog {
3 id: string;
4 userId?: string;
5 username?: string;
6 resourceName: string;
7 crudType: 'c' | 'r' | 'u' | 'd' | 'login';
8 from: string;
9 url?: string;
10 ip?: string;
11 when: string;
12 description?: string;
13 serverStartDate: string;
14 objectDetails?: object;
15}
16

The audit log is immutable. It also cannot be written to manually. FastComments.com may only decide when to write to the audit log. However, you may read from it via this API.

Events in the audit log expire after two years.

GET /api/v1/audit-logs Internal Link

Resource: AuditLog as GET /api/v1/audit-logs Credit Cost: 10

This API uses pagination, provided by the skip, before, and after parameters. AuditLogs are returned in pages of 1000, ordered by when and id.

Fetching every 1000 logs has a credit cost of 10.

By default, you will receive a list with the newest items first. This way, you can poll starting with skip=0, paginating until you find the last record you've consumed.

Alternatively, you can sort oldest-first, and paginate until there are no more records.

Sorting can be done by setting order to either ASC or DESC. The default is ASC.

Querying by date is possible via before and after as timestamps with milliseconds. before and after are NOT inclusive.

AuditLog cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/audit-logs?tenantId=demo&API_KEY=DEMO_API_SECRET&skip=0&order=ASC&before=123&after=456'
4
AuditLog Request Structure
Copy Copy
1
2interface CommentsRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5 order?: 'ASC' | 'DESC'
6 skip?: number
7 before?: number
8 after?: number
9}
10
AuditLog Response Structure
Copy Copy
1
2interface CommentsResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key'
6 /** Included on failure. **/
7 reason?: string
8 /** The logs! **/
9 auditLogs: AuditLog[]
10}
11

Comment Structure Internal Link

A Comment object represents a comment left by a user.

The relationship between parent and child comments is defined via parentId.

The structure for the Comment object is as follows:

Comment Structure
Copy Copy
1
2interface Comment {
3 /** READONLY: Set to true if the spam engine determined the comment was spam. **/
4 aiDeterminedSpam?: boolean
5 /** Whether the comment is approved to show. Set to true when saving the comment, else it will be hidden. **/
6 approved?: boolean
7 /** The user's avatar. **/
8 avatarSrc?: string
9 /** The commenter's raw comment. **/
10 comment: string
11 /** READONLY: The commenter's comment parsed into HTML. **/
12 commentHTML?: string
13 /** The commenter's email. Required if anonymous commenting is off. **/
14 commenterEmail?: string
15 /** The commenter's link (for example, their blog). **/
16 commenterLink?: string
17 /** The commenter's name. Always required. If not available, set to something like "Anonymous". **/
18 commenterName: string
19 /** The date the comment was left, in UTC epoch. **/
20 date: number
21 /** The "display label" for the comment - for example "Admin", "Moderator", or something like "VIP User". **/
22 displayLabel?: string
23 /** The domain the comment was posted on. **/
24 domain?: string
25 /** READONLY: The #hashtags written in the comment that were successfully parsed. **/
26 hashTags?: CommentHashTag[]
27 /** READONLY: Does the comment contain images? **/
28 hasImages?: boolean
29 /** READONLY: Does the comment contain links? **/
30 hasLinks?: boolean
31 /** READONLY: The unique comment id. **/
32 id: string
33 /** READONLY: Is the comment by an admin? Automatically set based on userId. **/
34 isByAdmin?: boolean
35 /** READONLY: Is the comment by a moderator? Automatically set based on userId. **/
36 isByModerator?: boolean
37 /** Is the comment pinned? **/
38 isPinned?: boolean
39 /** Is the comment spam? **/
40 isSpam?: boolean
41 /** The locale the comment is in. If not provided, will be derived from the language accept HTTP header. **/
42 locale?: 'de_de' | 'en_us' | 'es_es' | 'fr_fr' | 'it_it' | 'ja_jp' | 'ko_kr' | 'pl_pl' | 'pt_br' | 'ru_ru' | 'tr_tr' | 'zh_cn' | 'zh_tw'
43 /** READONLY: The @mentions written in the comment that were successfully parsed. **/
44 mentions?: CommentUserMention[]
45 /** Optional metadata associated with the comment. **/
46 meta?: Record<string, string | number | boolean>
47 /** The optional list of moderation group ids associated with this comment. **/
48 moderationGroupIds?: string[]|null
49 /** Whether notifications were sent for this comment for commenters. To prevent notifications being sent on imports, set this to true. **/
50 notificationSentForParent?: boolean
51 /** Whether notifications were sent for this comment for tenant users. To prevent notifications being sent on imports, set this to true. **/
52 notificationSentForParentTenant?: boolean
53 /** The title of the page this comment was on. **/
54 pageTitle?: string
55 /** If we're replying to a comment, this is the ID that we are replying to. **/
56 parentId?: string|null
57 /** Whether the comment is marked reviewed. **/
58 reviewed: boolean
59 /** The tenant id where the comment belongs. **/
60 tenantId: string
61 /** The user that wrote the comment. Created automatically when saving a comment with a name/email. **/
62 userId?: string|null
63 /** The URL to the location that this comment is visible, like a blog post. **/
64 url: string
65 /** A "cleaned" version of the urlId you passed us. When saving, you specify this field, but when you fetch the comment back this will be "cleaned" and your original value moved to "urlIdRaw". **/
66 urlId: string
67 /** READONLY: The original urlId you passed us. **/
68 urlIdRaw?: string
69 /** Is the user and this comment verified? **/
70 verified: boolean
71 /** Number of votes up. **/
72 votesUp?: number
73 /** Number of votes down. **/
74 votesDown?: number
75 /** The "karma" of the comment (= votes up - votes down). **/
76 votes?: number
77}
78

Some of these fields are marked READONLY - these are returned by the API but cannot be set.

When users are tagged in a comment, the information is stored in a list called mentions. Each object in that list has the following structure.

The Comment Mentions Object
Copy CopyRun External Link
1
2interface CommentUserMention {
3 /** The user id. For SSO users, this will have your tenant id prefixed. **/
4 id: string
5 /** The final @mention tag text, including the @ symbol. **/
6 tag: string
7 /** The original @mention tag text, including the @ symbol. **/
8 rawTag: string
9 /** What type of user was tagged. user = FastComments.com account. sso = SSOUser. **/
10 type: 'user'|'sso'
11 /** If the user opts out of notifications, this will still be set to true. **/
12 sent: boolean
13}
14

When hashtags are used and successfully parsed, the information is stored in a list called hashTags. Each object in that list has the following structure.

The Comment HashTag Object
Copy CopyRun External Link
1
2interface CommentHashTag {
3 /** The hashtag id. **/
4 id: string
5 /** The final #hashtag tag text, including the # symbol. **/
6 tag: string
7 /** If the hashtag is associated with a custom URL, this will be defined. **/
8 url?: string
9}
10

GET /api/v1/comments Internal Link

Resource: Comment as GET /api/v1/comments Credit Cost: 10

Comments must be fetched by-page. You can fetch comments for all pages at once, but use caution.

Comments cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/comments?tenantId=demo&page=0&urlId=test&API_KEY=DEMO_API_SECRET&direction=MR'
4
Comments Request Structure
Copy Copy
1
2interface CommentsRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** The urlId (page url, or article id) the comments are associated with. **/
6 urlId: string
7 /** The page to fetch, starting with 0. Pass -1 for all comments. **/
8 page: number
9 /** The sort direction. Default is MR (Most Relevant). Other options are OF (Oldest First) and NF (Newest First). **/
10 direction: 'MR' | 'OF' | 'NF'
11}
12
Comments Response Structure
Copy Copy
1
2interface CommentsResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-url-id' | 'missing-date'
6 /** Included on failure. **/
7 reason?: string
8 /** The comments! **/
9 comments: Comment[]
10}
11

Helpful Tip

The Comment API requires a urlId. You can call the Pages API first, to see what the urlId values available to you look like.

GET /api/v1/comments/:id Internal Link

Resource: Comment as GET /api/v1/comments/:id Credit Cost: 1

This API provides the ability to fetch a single comment by id.

Comments Get-By-Id cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/comments/some-id?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
Comment Get-By-Id Request Structure
Copy Copy
1
2interface CommentsGetByIdQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Comments Get-By-Id Response Structure
Copy Copy
1
2interface CommentGetByIdResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'not-found' | 'missing-id'
6 /** Included on failure. **/
7 reason?: string
8 /** The comment! **/
9 comment?: Comment
10}
11

POST /api/v1/comments Internal Link

Resource: Comment as POST /api/v1/comments Credit Cost: 1

This API endpoint provides the ability to create comments.

Common use cases are custom UIs, integrations, or imports.

Notes:

  • This API can update the comment widget "live" if desired (this increases creditsCost from 1 to 2).
  • This API will automatically create user objects in our system if email is provided.
  • Trying to save two comments with different emails, but the same username, will result in an error for the second comment.
  • If you are specifying parentId, and a child comment has notificationSentForParent as false, we will send notifications for the parent comment. This is done every hour (we batch the notifications together to decrease the number of emails sent).
  • If you want to send welcome emails when creating users, or comment verification emails, set sendEmails to true in query parameters.
  • Comments created via this API will show up in the Analytics and Moderation pages of the admin app.
  • "bad words" are still masked in the commenter names and comment text if the setting is turned on.
  • Comments created via this API can still be checked for spam if desired.
  • Configuration such as max comment length, if configured via the Customization Rule admin page, will apply here.

The minimum data required to submit is a comment, that will show in the comment widget, is as follows:

Minimum Comment POST cURL Example
Copy Copy
1
2curl --request POST \
3 --url 'https://fastcomments.com/api/v1/comments?tenantId=demo&API_KEY=DEMO_API_SECRET&isLive=true' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "approved": true,
7 "comment": "some-comment",
8 "commenterName": "some-commenter-name",
9 "date": 1622644382148,
10 "urlId": "some-place",
11 "url": "https://exmaple.com/some-page",
12 "verified": true
13}'
14

A more realistic request may look like:

Comment POST cURL Example
Copy Copy
1
2curl --request POST \
3 --url 'https://fastcomments.com/api/v1/comments?tenantId=demo&API_KEY=DEMO_API_SECRET&isLive=true&doSpamCheck=true' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "approved": true,
7 "avatarSrc": "https://static.fastcomments.com/1605337537848-DSC_0841.JPG",
8 "comment": "some-comment",
9 "commenterName": "some-commenter-name",
10 "commenterEmail": "fordperfect@spaceship.com",
11 "date": 1622644382148,
12 "isSpam": false,
13 "locale": "en_us",
14 "notificationSentForParent": true,
15 "notificationSentForParentTenant": true,
16 "reviewed": true,
17 "urlId": "some-place",
18 "url": "https://exmaple.com/some-page",
19 "verified": true,
20 "votes": 1,
21 "votesUp": 2,
22 "votesDown": 1
23}'
24
Comment POST Request Structure
Copy Copy
1
2interface CommentPostQueryParams {
3 tenantId: string
4 API_KEY: string
5 doSpamCheck?: 'true' | 'false'
6 /** Whether the comment should appear "live" to users viewing instances of the comment widget with the same urlId. NOTE: Doubles credit cost from 1 to 2. **/
7 isLive?: 'true' | 'false'
8 sendEmails?: 'true' | 'false'
9 populateNotifications?: 'true' | 'false'
10}
11
Comment POST Response Structure
Copy Copy
1
2
3interface CommentPostResponse {
4 status: 'success' | 'failed'
5 /** Included on failure. **/
6 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-url-id' | 'empty-comment' | 'comment-too-big' | 'hash-tags-readonly' | 'mentions-readonly' | 'invalid-user' | 'unauthorized' | 'invalid-date' | 'invalid-name' | 'invalid-name-is-email' | 'banned' | 'invalid-email';
7 /** Included on failure. **/
8 reason?: string
9 /** The created comment. **/
10 comment?: Comment
11 /** The associated user, which may or may not have already existed. **/
12 user?: User
13}
14

DELETE /api/v1/comments/:id Internal Link

Resource: Comment as DELETE /api/v1/comments/:id Credit Cost: 1

This API endpoint provides the ability to delete a comment.

Notes:

  • This API can update the comment widget "live" if desired (this increases creditsCost from 1 to 2).
  • This API will delete all child comments.
Comment DELETE cURL Example
Copy Copy
1
2curl --request DELETE \
3 --url 'https://fastcomments.com/api/v1/comments/some-comment-id?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json'
5
Comment DELETE Request Structure
Copy Copy
1
2interface CommentDeleteQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** Whether the comment should be deleted "live" to users viewing instances of the comment widget with the same urlId. NOTE: Doubles credit cost from 1 to 2. **/
6 isLive?: 'true' | 'false'
7}
8
Comment DELETE Response Structure
Copy Copy
1
2
3interface CommentDeleteResponse {
4 status: 'success' | 'failed'
5 /** Included on failure. **/
6 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-id' | 'not-found'
7 /** Included on failure. **/
8 reason?: string
9}
10

HashTag Structure Internal Link

A HashTag object represents a tag that can be left by a user. HashTags can be used to link to an external piece of content or to tie related comments together.

The structure for the HashTag object is as follows:

HashTag Structure
Copy Copy
1
2interface HashTag {
3 /** Should start with the "#" or desired character. **/
4 tag: string
5 /** An optional URL that the hashtag can point to. Instead of filtering comments by hashtag, the UI will redirect to this upon click. **/
6 url?: string
7 /** READONLY **/
8 createdAt: string
9}
10

Notes:

  • In some API endpoints you will see that the hashtag is used in the URL. Remember to URI-Encoded values. For example, # should instead be represented as %23.
  • Some of these fields are marked READONLY - these are returned by the API but cannot be set.

GET /api/v1/hash-tags Internal Link

Resource: HashTag as GET /api/v1/hash-tags Credit Cost: 1

This API uses pagination, provided by the page query parameter. HashTags are returned in pages of 100, ordered by tag.

HashTag cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/hash-tags?tenantId=demo&page=0&API_KEY=DEMO_API_SECRET'
4
HashTag Request Structure
Copy Copy
1
2interface HashTagsRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** The page to fetch, starting with 0. **/
6 page: number
7}
8
HashTag Response Structure
Copy Copy
1
2interface HashTagsResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key'
6 /** Included on failure. **/
7 reason?: string
8 /** The hashtags! **/
9 hashTags: HashTag[]
10}
11

PATCH /api/v1/hash-tags/:tag Internal Link

Resource: HashTag as PATCH /api/v1/hash-tags/:tag Credit Cost: 1

This route provides the ability to update a single HashTag.

HashTag Update cURL Example
Copy Copy
1
2curl --request PATCH \
3 --url 'https://fastcomments.com/api/v1/hash-tags/%23example_hash_tag?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "url": "https://example.com/some-`page`"
7}'
8
HashTag Update Request Structure
Copy Copy
1
2interface HashTagPatchQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
HashTag Update Response Structure
Copy Copy
1
2interface HashTagPatchResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-hash-tag' | 'tag-does-not-exist' | 'url-too-long' | 'invalid-tag' | 'already-exists'
6 /** Included on failure. **/
7 reason?: string
8 hashTag?: HashTag; // We return the complete updated hashtag on success.
9}
10

POST /api/v1/hash-tags Internal Link

Resource: HashTag as POST /api/v1/hash-tags Credit Cost: 1

This route provides the ability to add a single HashTag.

HashTag Create cURL Example
Copy Copy
1
2curl --request POST \
3 --url 'https://fastcomments.com/api/v1/hash-tags?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "tag": "#example",
7 "url": "https://example.com/some-page"
8}'
9
HashTag Create Request Structure
Copy Copy
1
2interface HashTagPostQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
HashTag Create Response Structure
Copy Copy
1
2interface HashTagPostResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-hash-tag' | 'tag-does-not-exist' | 'url-too-long' | 'invalid-tag'
6 /** Included on failure. **/
7 reason?: string
8 hashTag?: HashTag; // We return the complete created hashtag on success.
9}
10

POST /api/v1/hash-tags/bulk Internal Link

Resource: HashTag as POST /api/v1/hash-tags/bulk Credit Cost: 1

This route provides the ability to add up to 100 HashTag objects at once.

HashTag Bulk Create cURL Example
Copy Copy
1
2curl --request PATCH \
3 --url 'https://fastcomments.com/api/v1/hash-tags/bulk?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "tags": [
7 {
8 "tag": "#example",
9 "url": "https://example.com/some-page"
10 }
11 ]
12}'
13
HashTag Bulk Create Request Structure
Copy Copy
1
2interface HashTagPostQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
HashTag Bulk Create Response Structure
Copy Copy
1
2interface HashTagBulkPostResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-hash-tag' | 'tag-does-not-exist' | 'url-too-long' | 'invalid-tag'
6 /** Included on failure. **/
7 reason?: string
8 results?: HashTagPostResponse[]; // We return a list of HashTagPostResponse objects for each provided tag.
9}
10

DELETE /api/v1/hash-tags/:tag Internal Link

Resource: HashTag as DELETE /api/v1/hash-tags/:tag Credit Cost: 1

This route provides the removal of a HashTag user by the provided tag.

Note that unless automatic HashTag creation is disabled, hashtags can be re-created by a user providing the hashtag when commenting.

HashTag Removal cURL Example
Copy Copy
1
2curl --request DELETE \
3 --url 'https://fastcomments.com/api/v1/hash-tags/%23example_hash_tag?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
HashTag Removal Request Structure
Copy Copy
1
2interface HashTagDeleteQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
HashTag Removal Response Structure
Copy Copy
1
2interface HashTagDeleteResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-hash-tag' | 'tag-does-not-exist'
6 /** Included on failure. **/
7 reason?: string
8}
9

Moderator Structure Internal Link

A Moderator object represents configuration for a moderator.

There are three types of moderators:

  1. Administrator users that have the isCommentModeratorAdmin flag.
  2. SSO Users with the isCommentModeratorAdmin flag.
  3. Regular commenters, or FastComments.com users, that are invited as Moderators.

The Moderator structure is used to represent the Moderation State of use case 3.

If you want to invite a user to be a moderator, via the API, use the Moderator API by creating a Moderator and inviting them.

If the user does not have a FastComments.com account, the invite email will help them get setup. If they already have an account, they will be given moderation access to your tenant and the Moderator object's userId will be updated to point to their user. You will not have API access to their user, as in this case it belongs to themselves and managed by FastComments.com.

If you require complete management of the user's account, we recommend either using SSO, or adding them as a Tenant User and then adding a Moderator object to track their stats.

The Moderator structure can be used as a stat tracking mechanism for use cases 1 and 2. After creating the user, add a Moderator object with their userId defined and their stats will be tracked on the Comment Moderators Page.

The structure for the Moderator object is as follows:

Moderator Structure
Copy Copy
1
2interface Moderator {
3 name: string
4 email: string
5 tenantId: string
6 userId?: string|null
7 acceptedInvite?: boolean
8 markReviewedCount?: number
9 deletedCount?: number
10 markedSpamCount?: number
11 approvedCount?: number
12 editedCount?: number
13 bannedCount?: number
14 createdAt: string
15 moderationGroupIds?: string[]|null
16}
17

GET /api/v1/moderators/:id Internal Link

Resource: Moderator as GET /api/v1/moderators/:id Credit Cost: 1

This route returns a single moderator by their id.

Moderator By ID cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/moderators/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
Moderator Request Structure
Copy Copy
1
2interface ModeratorByIdQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Moderator Response Structure
Copy Copy
1
2interface ModeratorByIdResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-id' | 'not-found'
6 /** Included on failure. **/
7 reason?: string
8 moderator?: Moderator
9}
10

GET /api/v1/moderators Internal Link

Resource: Moderator as GET /api/v1/moderators Credit Cost: 1

This API uses pagination, provided by the skip query parameter. Moderators are returned in pages of 100, ordered by createdAt and id.

The cost is based on the number of moderators returned, costing 1 credit per 10 moderators returned.

Moderator cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/moderators?tenantId=demo&skip=0&API_KEY=DEMO_API_SECRET'
4
Moderator Request Structure
Copy Copy
1
2interface ModeratorsRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** The number of moderators to skip for pagination. **/
6 skip?: number
7}
8
Moderator Response Structure
Copy Copy
1
2interface ModeratorsResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key'
6 /** Included on failure. **/
7 reason?: string
8 moderators?: Moderator[]
9}
10

PATCH /api/v1/moderators/:id Internal Link

Resource: Moderator as PATCH /api/v1/moderators/:id Credit Cost: 1

This API endpoint provides the ability to update a Moderator by id.

Updating a Moderator has the following restrictions:

  • The following values may not be provided when updating a Moderator:
    • acceptedInvite
    • markReviewedCount
    • deletedCount
    • markedSpamCount
    • approvedCount
    • editedCount
    • bannedCount
    • verificationId
    • createdAt
  • When a userId is specified, that user must exist.
  • When a userId is specified, they must belong to the same tenantId specified in query params.
  • Two moderators in the same tenant cannot be added with the same email.
  • You may not change the tenantId associated with a Moderator.
Moderator PATCH cURL Example
Copy Copy
1
2curl --request PATCH \
3 --url 'https://fastcomments.com/api/v1/moderators/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "name": "Some New Name",
7}'
8
Moderator PATCH Request Structure
Copy Copy
1
2interface ModeratorPatchQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Moderator PATCH Response Structure
Copy Copy
1
2
3interface ModeratorPatchResponse {
4 status: 'success' | 'failed'
5 /** Included on failure. **/
6 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'name-required' | 'email-required' | 'unexpected-param' | 'not-found';
7 /** Included on failure. **/
8 reason?: string
9}
10

POST /api/v1/moderators Internal Link

Resource: Moderator as POST /api/v1/moderators Credit Cost: 1

This route provides the ability to add a single Moderator.

Creating a Moderator has the following restrictions:

  • A name and email must always be provided. A userId is optional.
  • The following values may not be provided when creating a Moderator:
    • acceptedInvite
    • markReviewedCount
    • deletedCount
    • markedSpamCount
    • approvedCount
    • editedCount
    • bannedCount
    • verificationId
    • createdAt
  • When a userId is specified, that user must exist.
  • When a userId is specified, they must belong to the same tenantId specified in query params.
  • Two moderators in the same tenant cannot be added with the same email.

We can create a Moderator for a user which we only know the email:

Moderator Create via Email cURL Example
Copy Copy
1
2curl --request POST \
3 --url 'https://fastcomments.com/api/v1/moderators?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "name": "Some Name",
7 "email": "someone@someone.com"
8}'
9

Or we can create a Moderator for a user which belongs to our tenant, to track their moderation stats:

Moderator Create via Tenant User cURL Example
Copy Copy
1
2curl --request POST \
3 --url 'https://fastcomments.com/api/v1/moderators?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "name": "Some Name",
7 "email": "someone@someone.com",
8 "userId": "some-tenant-user-id"
9}'
10
Moderator Create Request Structure
Copy Copy
1
2interface ModeratorPostQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Moderator Create Response Structure
Copy Copy
1
2interface ModeratorPostResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'name-required' | 'email-required' | 'unexpected-param' | 'not-found'
6 /** Included on failure. **/
7 reason?: string
8 moderator?: Moderator; // We return the complete created moderator on success.
9}
10

POST /api/v1/moderators/:id/send-invite Internal Link

Resource: Moderator as POST /api/v1/moderators/:id/send-invite Credit Cost: 10

This route provides the ability to invite a single Moderator.

The following restrictions exist to send an invite email to a Moderator:

  • The Moderator must already exist.
  • The fromName may not be longer than 100 characters.

Notes:

  • If a user with the provided email already exists, they will be invited to moderate your tenant's comments.
  • If a user with the provided email does not exist the invite link will guide them through creating their account.
  • The invite will expire after 30 days.

We can create a Moderator for a user which we only know the email:

Moderator Invite cURL Example
Copy Copy
1
2curl --request POST \
3 --url 'https://fastcomments.com/api/v1/moderators/xyz/send-invite?tenantId=demo&API_KEY=DEMO_API_SECRET&fromName=Bob' \
4 --header 'Content-Type: application/json'
5

This will send an email like Bob at TenantName is inviting you to be a moderator...

Moderator Invite Request Structure
Copy Copy
1
2interface ModeratorSendInviteQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** The email sent to the user will appear to be sent from this name. **/
6 fromName: string
7}
8
Moderator Invite Response Structure
Copy Copy
1
2interface ModeratorSendInviteResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'unauthorized' | 'not-found | 'from-name-required' | 'from-name-invalid'
6 /** Included on failure. **/
7 reason?: string
8}
9

DELETE /api/v1/moderators/:id Internal Link

Resource: Moderator as DELETE /api/v1/moderators/:id Credit Cost: 5

This route provides the removal of a Moderator by id.

Moderator Removal cURL Example
Copy Copy
1
2curl --request DELETE \
3 --url 'https://fastcomments.com/api/v1/moderators/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
Moderator Removal Request Structure
Copy Copy
1
2interface ModeratorDeleteQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Moderator Removal Response Structure
Copy Copy
1
2interface ModeratorDeleteResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'not-found'
6 /** Included on failure. **/
7 reason?: string
8}
9

Page Structure Internal Link

A Page object represents the page that many comments may belong to. This relationship is defined by urlId.

A Page stores information such as the page title, comment count, and urlId.

The structure for the Page object is as follows:

Page Structure
Copy Copy
1
2interface Page {
3 id: string
4 urlId: string
5 url: string
6 title?: string
7 createdAt: string
8 commentCount: number
9 rootCommentCount: number
10 /** Setting this to null means all SSO users can see the page. An empty list means it is closed to call users. **/
11 accessibleByGroupIds?: string[] | null
12}
13

GET /api/v1/pages Internal Link

Resource: Page as GET /api/v1/pages Credit Cost: 10

You can currently only fetch all pages (or a single page via /by-url-id) associated with your account. If you'd like more fine-grained searching, reach out to us.

Pages cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/pages?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
Pages Request Structure
Copy Copy
1
2interface PagesRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Pages Response Structure
Copy Copy
1
2interface PagesResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key'
6 /** Included on failure. **/
7 reason?: string
8 pages: Page[]
9}
10

Helpful Tip

The Comment API requires a urlId. You can call the Pages API first, to see what the urlId values available to you look like.

GET /api/v1/pages/by-url-id Internal Link

Resource: Page as GET /api/v1/pages/by-url-id Credit Cost: 1

Individual pages can be fetched by their corresponding urlId. This can be useful for looking up page titles or comment counts.

Page by URL ID cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/pages/by-url-id?tenantId=demo&API_KEY=DEMO_API_SECRET&urlId=example-id-or-url'
4
Page By URL ID Request Structure
Copy Copy
1
2interface PagesRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5 urlId: string
6}
7
Page by URL ID Response Structure
Copy Copy
1
2interface PagesResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-url-id'
6 /** Included on failure. **/
7 reason?: string
8 page?: Page[] | null
9}
10

Helpful Tip

Remember to URI Encode values like the urlId.

PATCH /api/v1/pages/:id Internal Link

Resource: Page as PATCH /api/v1/pages/:id Credit Cost: 1

This route provides the ability to update a single Page.

Page Update cURL Example
Copy Copy
1
2curl --request PATCH \
3 --url 'https://fastcomments.com/api/v1/pages/my-page-id?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "url": "https://example.com/some-page"
7}'
8
Page Update Request Structure
Copy Copy
1
2interface PagePatchQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Page Update Response Structure
Copy Copy
1
2interface PagePatchResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-url-id' | 'missing-id' | 'page-does-not-exist' | 'empty-request' | 'internal' | 'invalid-input' | 'invalid-title' | 'extra-params' | 'accessible-by-group-ids-not-array' | 'too-many-group-ids' | 'group-id-too-large'
6 /** Included on failure. **/
7 reason?: string
8 user?: Page; // We return the complete updated page on success.
9}
10

Note

Some parameters in the Page object get automatically updated. These are the counts and title attributes. Counts cannot be updated via the API since they are calculated values. The page title can be set via the API, but would get overwritten if the comment widget is used on a page with the same urlId and a different page title.

POST /api/v1/pages Internal Link

Resource: Page as POST /api/v1/pages Credit Cost: 1

This API endpoint provides the ability to create pages.

A common use cases is access control.

Notes:

  • If you've commented on a comment thread, or called the API to create a Comment, you've already created a Page object! You can try fetching it via the /by-url-id Page route, passing in the same urlId passed to the comment widget.
  • The Page structure contains some calculated values. Currently, these are commentCount and rootCommentCount. They are populated automatically and cannot be set by the API. Attempting to do so will cause the API to return an error.
Page POST cURL Example
Copy Copy
1
2curl --request POST \
3 --url 'https://fastcomments.com/api/v1/pages?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "title": "Test Page",
7 "url": "some0-url",
8 "urlId": "page2",
9 "accessibleByGroupIds": ["SOME_GROUP_ID"]
10}'
11
Page POST Request Structure
Copy Copy
1
2interface PagePostQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Page POST Response Structure
Copy Copy
1
2
3interface PagePostResponse {
4 status: 'success' | 'failed'
5 /** Included on failure. **/
6 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-url-id' | 'empty-request' | 'internal' | 'invalid-input' | 'invalid-title' | 'extra-params' | 'accessible-by-group-ids-not-array' | 'too-many-group-ids' | 'group-id-too-large';
7 /** Included on failure. **/
8 reason?: string
9 /** The created page. **/
10 page?: Page
11}
12

DELETE /api/v1/pages/:id Internal Link

Resource: Page as DELETE /api/v1/pages/:id Credit Cost: 1

This route provides the removal of a single page by id.

Note that interacting with the comment widget for a page with the same urlId will simply recreate the Page seamlessly.

Page Removal cURL Example
Copy Copy
1
2curl --request DELETE \
3 --url 'https://fastcomments.com/api/v1/pages/some-page-id?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
Page Removal Request Structure
Copy Copy
1
2interface PageDeleteQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Page Removal Response Structure
Copy Copy
1
2interface PageDeleteResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-id' | 'page-does-not-exist'
6 /** Included on failure. **/
7 reason?: string
8}
9

SSOUser Structure Internal Link

FastComments provides an easy to use SSO solution. Updating a user's information with the HMAC-based integration is as simple as having the user load the page with an updated payload.

However, it may be desirable to manage a user outside that flow, to improve consistency of your application.

The SSO User API provides a way to CRUD objects that we call SSOUsers. These objects are different from regular Users and kept separate for type safety.

The structure for the SSOUser object is as follows:

SSOUser Structure
Copy Copy
1
2interface SSOUser {
3 id: string
4 username: string
5 email?: string
6 websiteUrl?: string
7 signUpDate: number
8 createdFromUrlId?: string
9 loginCount?: number
10 avatarSrc?: string
11 optedInNotifications?: boolean
12 displayLabel?: string
13 displayName?: string
14 isAccountOwner?: boolean
15 isAdminAdmin?: boolean
16 isCommentModeratorAdmin?: boolean
17 /** If null, Access Control will not be applied to the user. If an empty list, this user will not be able to see any pages or @mention other users. **/
18 groupIds?: string[] | null
19 createdFromSimpleSSO?: boolean
20 /** Don't let other users see this user's activity, including comments, on their profile. Default is true to provide secure profiles by default. **/
21 isProfileActivityPrivate?: boolean
22}
23

Access Control

Users can be broken into groups. This is what the groupIds field is for, and is optional.

@Mentions

By default @mentions will use username to search for other sso users when the @ character is typed. If displayName is used, then results matching username will be ignored when there is a match for displayName, and the @mention search results will use displayName.

GET /api/v1/sso-users Internal Link

Resource: SSOUser as GET /api/v1/sso-users Credit Cost: 10

This route returns SSO Users in pages of 100. Pagination is provided by the skip parameter. Users are sorted by their signUpDate and id.

SSOUsers cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/sso-users?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
SSOUsers Request Structure
Copy Copy
1
2interface SSOUsersRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5 skip?: number
6}
7
SSOUsers Response Structure
Copy Copy
1
2interface SSOUsersResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key'
6 /** Included on failure. **/
7 reason?: string
8 users: SSOUser[]
9}
10

GET /api/v1/sso-users/by-id/:id Internal Link

Resource: SSOUser as GET /api/v1/sso-users/by-id/:id Credit Cost: 1

This route returns a single SSO user by their id.

SSOUser By ID cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/sso-users/by-id/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
SSOUser Request Structure
Copy Copy
1
2interface SSOUserRequestByIdQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
SSOUser Response Structure
Copy Copy
1
2interface SSOUserByIdResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-id' | 'user-does-not-exist'
6 /** Included on failure. **/
7 reason?: string
8 user: SSOUser
9}
10

GET /api/v1/sso-users/by-email/:email Internal Link

Resource: SSOUser as GET /api/v1/sso-users/by-id/:id Credit Cost: 1

This route returns a single SSO user by their email.

SSOUser By Email cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/sso-users/by-email/someone@somewhere.com?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
SSOUser Request Structure
Copy Copy
1
2interface SSOUserRequestByEmailQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
SSOUser Response Structure
Copy Copy
1
2interface SSOUserByEmailResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-email' | 'user-does-not-exist'
6 /** Included on failure. **/
7 reason?: string
8 user: SSOUser
9}
10

PATCH /api/v1/sso-users/:id Internal Link

Resource: SSOUser as PATCH /api/v1/sso-users/:id Credit Cost: 1

This route provides the ability to update a single SSO user.

SSOUser Update cURL Example
Copy Copy
1
2curl --request PATCH \
3 --url 'https://fastcomments.com/api/v1/sso-users/my-user-id?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "username": "notfordperfect"
7}'
8
SSOUser Update Request Structure
Copy Copy
1
2interface SSOUserPatchQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** When email or username is changed, you can set this to true to also update the user's comments. This will double the credit cost. **/
6 updateComments: 'true' | 'false'
7}
8
SSOUser Update Response Structure
Copy Copy
1
2interface SSOUserPatchResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'empty-request' | 'invalid-input' | 'missing-id' | 'user-does-not-exist'
6 /** Included on failure. **/
7 reason?: string
8 user?: SSOUser; // We return the complete updated user on success.
9}
10

POST /api/v1/sso-users Internal Link

Resource: SSOUser as POST /api/v1/sso-users Credit Cost: 1

This route provides the creation of a single SSO user.

Trying to create two users with the same ID will result in an error.

SSOUser Creation cURL Example
Copy Copy
1
2curl --request POST \
3 --url 'https://fastcomments.com/api/v1/sso-users?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "id": "my-user-id",
7 "username": "fordperfect",
8 "displayName": "Ford Perfect",
9 "email": "fordperfect@galaxy.com",
10 "groupIds": ["some-optional-group-id"]
11}'
12

In this example we specify groupIds for access control, but this is optional.

SSOUser Creation Request Structure
Copy Copy
1
2interface SSOUserPostQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
SSOUser Creation Response Structure
Copy Copy
1
2interface SSOUserPostResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'empty-request' | 'invalid-input' | 'missing-id' | 'user-exists'
6 /** Included on failure. **/
7 reason?: string
8 user?: SSOUser; // We return the created user on success.
9}
10

Integration Note

Data passed by the API can be overridden simply by passing a different SSO User HMAC payload. For example, if you set a username via the API, but then pass a different one via the SSO flow on page load, we will automatically update their username.

We will not update user parameters in this flow unless you explicitly specify them or set them to null (not undefined).

PUT /api/v1/sso-users/:id Internal Link

Resource: SSOUser as PUT /api/v1/sso-users Credit Cost: 1

This route provides the ability to update a single SSO user.

SSOUser Update cURL Example
Copy Copy
1
2curl --request PUT \
3 --url 'https://fastcomments.com/api/v1/sso-users/my-user-id?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "username": "fordperfect",
7 "displayName": "Ford Perfect",
8 "email": "fordperfect@galaxy.com",
9 "groupIds": ["some-optional-group-id"]
10}'
11

In this example we specify groupIds for access control, but this is optional.

SSOUser Update Request Structure
Copy Copy
1
2interface SSOUserPutQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** When email or username is changed, you can set this to true to also update the user's comments. This will double the credit cost. **/
6 updateComments: 'true' | 'false'
7}
8
SSOUser Update Response Structure
Copy Copy
1
2interface SSOUserPutResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'empty-request' | 'invalid-input' | 'missing-id' | 'user-exists'
6 /** Included on failure. **/
7 reason?: string
8 user?: SSOUser; // We return the update user on success.
9}
10

DELETE /api/v1/sso-users/:id Internal Link

Resource: SSOUser as DELETE /api/v1/sso-users/:id Credit Cost: 1

This route provides the removal of a single SSO user by their email.

Note that loading the comment widget again with a payload for this user will simply recreate the user seamlessly.

SSOUser Removal cURL Example
Copy Copy
1
2curl --request DELETE \
3 --url 'https://fastcomments.com/api/v1/sso-users/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
SSOUser Removal Request Structure
Copy Copy
1
2interface SSOUsersDeleteQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** You can set this to true to also delete the user's comments. This will double the credit cost. **/
6 deleteComments: 'true' | 'false'
7}
8
SSOUser Removal Response Structure
Copy Copy
1
2interface SSOUsersResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-id' | 'user-does-not-exist'
6 /** Included on failure. **/
7 reason?: string
8 user?: SSOUser; // We return the removed user on success.
9}
10

TenantDailyUsage Structure Internal Link

A TenantDailyUsage object represents the usage for a tenant on a given day. If there was no activity for a given tenant on a given day, that day will not have a TenantDailyUsage object.

The TenantDailyUsage object is not real time and may be minutes behind actual usage.

The structure for the TenantDailyUsage object is as follows:

TenantDailyUsage Structure
Copy Copy
1
2export interface TenantDailyUsage {
3 yearNumber: number
4 monthNumber: number
5 dayNumber: number
6 commentFetchCount?: number
7 commentCreateCount?: number
8 conversationCreateCount?: number
9 voteCount?: number
10 accountCreatedCount?: number
11 userMentionSearch?: number
12 hashTagSearch?: number
13 gifSearchTrending?: number
14 gifSearch?: number
15 apiCreditsUsed?: number
16 createdAt: string
17 billed: boolean
18 /** Ignored for billing. **/
19 ignored: boolean
20}
21

GET /api/v1/tenant-daily-usage Internal Link

Resource: TenantDailyUsage as GET /api/v1/tenant-daily-usage Credit Cost: 1

This route allows searching for the usage of a tenant by year, month, and day. Up to 365 objects can be returned, and the cost is 1 api credit per 10 objects.

Response objects are sorted by the date they are created (the oldest first).

TenantDailyUsage Search cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/tenant-daily-usage?tenantId=demo&API_KEY=DEMO_API_SECRET&yearNumber=2022&monthNumber=2&dayNumber=10'
4
TenantDailyUsage Request Structure
Copy Copy
1
2interface TenantDailyUsageQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** Based on UTC. **/
6 yearNumber?: number
7 /** Zero-based. Based on UTC. **/
8 monthNumber?: number
9 /** One-based. Based on UTC. **/
10 dayNumber?: number
11}
12
TenantDailyUsage Response Structure
Copy Copy
1
2interface TenantDailyUsageResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-id' | 'not-found'
6 /** Included on failure. **/
7 reason?: string
8 tenantDailyUsages: TenantDailyUsage[]
9}
10

Tenant Structure Internal Link

The Tenant defines a FastComments.com customer. They can be created via the API by tenants with white labeling access. White labeled tenants cannot create other white labeled tenants (only one level of nesting is allowed).

The structure for the Tenant object is as follows:

Tenant Structure
Copy Copy
1
2export enum SiteType {
3 Unknown = 0,
4 WordPress = 1
5}
6
7/** This can also be handled via the DomainConfig API. **/
8export interface TenantDomainConfig {
9 domain: string
10 emailFromName?: string
11 emailFromEmail?: string
12 createdAt?: string,
13 siteType?: FastCommentsSiteType, // you probably want Unknown
14 logoSrc?: string, // raw image path
15 logoSrc100px?: string, // resized for thumbnails
16 footerUnsubscribeURL?: string,
17 emailHeaders?: Record<string, string>,
18 disableUnsubscribeLinks?: boolean,
19 dkim?: {
20 domainName: string,
21 keySelector: string,
22 privateKey: string
23 }
24}
25
26export interface TenantBillingInfo {
27 name: string
28 address: string
29 city: string
30 state: string
31 zip: string
32 country: string
33}
34
35export enum TenantPaymentFrequency {
36 Monthly = 0,
37 Annually = 1
38}
39
40export interface Tenant {
41 id: string
42 name: string
43 email: string
44 signUpDate: number; // number due to "legacy" reasons
45 packageId?: string | null
46 paymentFrequency?: TenantPaymentFrequency
47 billingInfoValid?: boolean
48 billingHandledExternally?: boolean
49 createdBy?: string
50 isSetup?: boolean
51 domainConfiguration: FastCommentsAPITenantDomainConfig[]
52 billingInfo?: FastCommentsAPITenantBillingInfo
53 stripeCustomerId?: string
54 stripeSubscriptionId?: string
55 stripePlanId?: string
56 enableProfanityFilter?: boolean
57 enableSpamFilter?: boolean
58 lastBillingIssueReminderDate?: string
59 removeUnverifiedComments?: boolean
60 unverifiedCommentsTTLms?: number
61 commentsRequireApproval?: boolean
62 autoApproveCommentOnVerification?: boolean
63 sendProfaneToSpam?: boolean
64 /** @readonly - Is calculated based on packageId. **/
65 hasFlexPricing?: boolean
66 /** @readonly **/
67 flexLastBilledAmount?: number
68 /** @readonly - Is calculated based on packageId. **/
69 hasAuditing?: boolean
70}
71

GET /api/v1/tenants/:id Internal Link

Resource: Tenant as GET /api/v1/tenants/:id Credit Cost: 1

This route returns a single Tenant by id.

Tenant By ID cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/tenants/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
Tenant Request Structure
Copy Copy
1
2interface TenantByIdQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Tenant Response Structure
Copy Copy
1
2interface TenantByIdResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-id' | 'not-found' | 'unauthorized'
6 /** Included on failure. **/
7 reason?: string
8 tenant?: Tenant
9}
10

GET /api/v1/tenants Internal Link

Resource: Tenant as GET /api/v1/tenants Credit Cost: 1

This API returns tenants that are managed by your tenant.

Pagination is provided by the skip query parameter. Tenants are returned in pages of 100, ordered by signUpDate, and id.

The cost is based on the number of tenants returned, costing 1 credit per 10 tenants returned.

Tenant cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/tenants?tenantId=demo&skip=0&API_KEY=DEMO_API_SECRET'
4
Tenant Request Structure
Copy Copy
1
2interface TenantsRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** The number of tenants to skip for pagination. **/
6 skip?: number
7}
8
Tenant Response Structure
Copy Copy
1
2interface TenantsResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key'
6 /** Included on failure. **/
7 reason?: string
8 tenants?: Tenant[]
9}
10

POST /api/v1/tenants Internal Link

Resource: Tenant as POST /api/v1/tenants Credit Cost: 1

This route provides the ability to add a single Tenant.

Creating a Tenant has the following restrictions:

  • A name is required.
  • A email is required.
  • domainConfiguration is required.
  • The following values may not be provided when creating a Tenant:
    • hasFlexPricing
    • lastBillingIssueReminderDate
    • flexLastBilledAmount
  • The signUpDate may not be in the future.
  • The name may not be longer than 200 characters.
  • The email may not be longer than 300 characters.
  • The email must be unique across all of FastComments.com tenants.
  • You may not create tenants if the parent tenant does not have a valid TenantPackage defined.
    • If your tenant was created via FastComments.com, this shouldn't be an issue.
  • You may not create more tenants than defined under maxWhiteLabeledTenants in your package.
  • You must specify the tenantId query param which is the id of your parent tenant with white labeling enabled.

We can create a Tenant with only a few parameters:

Tenant Create cURL Example
Copy Copy
1
2curl --request POST \
3 --url 'https://fastcomments.com/api/v1/tenants?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "name": "Some Name",
7 "email": "someone@someone.com",
8 "domainConfiguration": [ { "domain": "somedomain.com" } ]
9}'
10
Tenant Create Request Structure
Copy Copy
1
2interface TenantPostQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Tenant Create Response Structure
Copy Copy
1
2interface TenantPostResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'unexpected-param' | 'not-found' | 'unexpected-param' | 'sign-up-date-in-future' | 'payment-frequency-invalid' | 'cannot-change-payment-frequency' | 'name-invalid' | 'email-invalid' | 'email-taken' | 'no-package' | 'invalid-package' | 'unauthorized' | 'tenant-limit-reached' | 'cannot-move-tenant' | 'cannot-change-package' | 'invalid-billing-info'
6 /** Included on failure. **/
7 reason?: string
8 tenant?: Tenant; // We return the complete created tenant on success.
9}
10

PATCH /api/v1/tenants/:id Internal Link

Resource: Tenant as PATCH /api/v1/tenants/:id Credit Cost: 1

This API endpoint provides the ability to update a Tenant by id.

Updating a Tenant has the following restrictions:

  • The following values may not be updated:
    • hasFlexPricing
    • lastBillingIssueReminderDate
    • flexLastBilledAmount
    • managedByTenantId
  • The signUpDate may not be in the future.
  • The name may not be longer than 200 characters.
  • The email may not be longer than 300 characters.
  • The email must be unique across all of FastComments.com tenants.
  • When setting billingInfoValid to true, billingInfo must be provided in the same request.
  • You may not update the packageId associated with your own tenant.
  • You may not update the paymentFrequency associated with your own tenant.
Tenant PATCH cURL Example
Copy Copy
1
2curl --request PATCH \
3 --url 'https://fastcomments.com/api/v1/tenants/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "name": "Some New Name",
7}'
8
Tenant PATCH Request Structure
Copy Copy
1
2interface TenantPatchQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Tenant PATCH Response Structure
Copy Copy
1
2
3interface TenantPatchResponse {
4 status: 'success' | 'failed'
5 /** Included on failure. **/
6 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'unexpected-param' | 'not-found' | 'unexpected-param' | 'sign-up-date-in-future' | 'payment-frequency-invalid' | 'cannot-change-payment-frequency' | 'name-invalid' | 'email-invalid' | 'email-taken' | 'no-package' | 'invalid-package' | 'unauthorized' | 'tenant-limit-reached' | 'cannot-move-tenant' | 'cannot-change-package' | 'invalid-billing-info';
7 /** Included on failure. **/
8 reason?: string
9}
10

DELETE /api/v1/tenants/:id Internal Link

Resource: Tenant as DELETE /api/v1/tenants/:id Credit Cost: 1,000

This route provides the removal of a Tenant and all associated data (users, comments, etc) by id.

The following restrictions exist around removing tenants:

  • The tenant must be your own, or a white labeled tenant that you manage.
  • The sure query parameter must be set to true.
Tenant Removal cURL Example
Copy Copy
1
2curl --request DELETE \
3 --url 'https://fastcomments.com/api/v1/tenants/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
Tenant Removal Request Structure
Copy Copy
1
2interface TenantDeleteQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Tenant Removal Response Structure
Copy Copy
1
2interface TenantDeleteResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'not-found' | 'unauthorized' | 'unsure'
6 /** Included on failure. **/
7 reason?: string
8}
9

Tenant Package Structure Internal Link

The TenantPackage defines package information available to a Tenant. A tenant may have many packages available, but only one in use at a given time.

A Tenant cannot be used for any products until its packageId points to a valid TenantPackage.

There are two types of TenantPackage objects:

  1. Fixed-pricing packages - where hasFlexPricing is false.
  2. Flexible pricing - where hasFlexPricing is true.

In both case limits are defined on the account using the package, however with Flex the tenant is charged a base price plus what they used, defined by the flex* parameters.

A tenant may have multiple tenant packages and have the ability to change the package themselves from the Billing Info Page.

If you will be handling billing for tenants yourselves, you will still need to define a package for each tenant to define their limits. Simply set billingHandledExternally to true on the Tenant and they will not be able to change their billing information, or active package, themselves.

You may not create packages with higher limits than the parent tenant.

The structure for the TenantPackage object is as follows:

TenantPackage Structure
Copy Copy
1
2export interface TenantPackage {
3 id: string
4 name: string
5 tenantId: string
6 createdAt: string
7 monthlyCostUSD: number
8 yearlyCostUSD: number
9 monthlyStripePlanId?: string
10 yearlyStripePlanId?: string
11 maxMonthlyPageLoads: number
12 maxMonthlyAPICredits: number
13 maxMonthlyComments: number
14 maxConcurrentUsers: number
15 maxTenantUsers: number
16 maxSSOUsers: number
17 maxModerators: number
18 maxDomains: number
19 maxWhiteLabeledTenants: number
20 hasWhiteLabeling: boolean
21 hasDebranding: boolean
22 forWhoText: string
23 featureTaglines: string[]
24 hasAuditing: boolean
25 hasFlexPricing: boolean
26 flexPageLoadCostCents?: null
27 flexPageLoadUnit?: null
28 flexCommentCostCents?: null
29 flexCommentUnit?: null
30 flexSSOUserCostCents?: null
31 flexSSOUserUnit?: null
32 flexAPICreditCostCents?: null
33 flexAPICreditUnit?: null
34 flexModeratorCostCents?: null
35 flexModeratorUnit?: null
36 flexAdminCostCents?: null
37 flexAdminUnit?: null
38 flexDomainCostCents?: null
39 flexDomainUnit?: null
40 flexMinimumCostCents?: null
41}
42

GET /api/v1/tenant-packages/:id Internal Link

Resource: TenantPackage as GET /api/v1/tenant-packages/:id Credit Cost: 1

This route returns a single Tenant Package by id.

TenantPackage By ID cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/tenant-packages/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
TenantPackage Request Structure
Copy Copy
1
2interface TenantPackageByIdQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
TenantPackage Response Structure
Copy Copy
1
2interface TenantPackageByIdResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-id' | 'not-found'
6 /** Included on failure. **/
7 reason?: string
8 tenantPackage: TenantPackage
9}
10

GET /api/v1/tenant-packages Internal Link

Resource: TenantPackage as GET /api/v1/tenant-packages Credit Cost: 1

This API uses pagination, provided by the skip query parameter. TenantPackages are returned in pages of 100, ordered by createdAt and id.

The cost is based on the number of tenant packages returned, costing 1 credit per 10 tenant packages returned.

TenantPackage cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/tenant-packages?tenantId=demo&skip=0&API_KEY=DEMO_API_SECRET'
4
TenantPackage Request Structure
Copy Copy
1
2interface TenantPackagesRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** The number of tenant packages to skip for pagination. **/
6 skip?: number
7}
8
TenantPackage Response Structure
Copy Copy
1
2interface TenantPackagesResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key'
6 /** Included on failure. **/
7 reason?: string
8 tenantPackages?: TenantPackage[]
9}
10

POST /api/v1/tenant-packages Internal Link

Resource: TenantPackage as POST /api/v1/tenant-packages Credit Cost: 1

This route provides the ability to add a single TenantPackage.

Creating a TenantPackage has the following restrictions:

  • The following parameters are required:
    • name
    • tenantId
    • monthlyCostUSD - Can be null.
    • yearlyCostUSD - Can be null.
    • maxMonthlyPageLoads
    • maxMonthlyAPICredits
    • maxMonthlyComments
    • maxConcurrentUsers
    • maxTenantUsers
    • maxSSOUsers
    • maxModerators
    • maxDomains
    • hasDebranding
    • forWhoText
    • featureTaglines
    • hasFlexPricing - If true, then all flex* parameters are required.
  • The name may not be longer than 50 characters.
  • Each forWhoText item may not be longer than 200 characters.
  • Each featureTaglines item may not be longer than 100 characters.
  • The TenantPackage must be "smaller" than the parent tenant. For example, all of the max* parameters must have lower values than the parent tenant.
  • A white labeled tenant may have a maximum of five packages.
  • Only tenants with white labeling access may create a TenantPackage.
  • You may not add packages to your own tenant. :)

We can create a TenantPackage as follows:

TenantPackage Create via Email cURL Example
Copy Copy
1
2curl --request PATCH \
3 --url 'https://fastcomments.com/api/v1/tenant-packages?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "name": "Default Package",
7 "tenantId": "some-child-tenant-id",
8 "monthlyCostUSD": null,
9 "yearlyCostUSD": null,
10 "maxMonthlyPageLoads": 50000,
11 "maxMonthlyAPICredits": 50000,
12 "maxMonthlyComments": 50000,
13 "maxConcurrentUsers": 50000,
14 "maxTenantUsers": 10,
15 "maxSSOUsers": 50000,
16 "maxModerators": 100,
17 "maxDomains": 3,
18 "hasWhiteLabeling": false,
19 "hasDebranding": true,
20 "forWhoText": "For Everyone",
21 "featureTaglines": [
22 "Some Tag",
23 "Some Other Tag"
24 ],
25 "hasFlexPricing": true,
26 "flexPageLoadCostCents": 100,
27 "flexPageLoadUnit": 100000,
28 "flexCommentCostCents": 100,
29 "flexCommentUnit": 100000,
30 "flexSSOUserCostCents": 100,
31 "flexSSOUserUnit": 1000,
32 "flexAPICreditCostCents": 100,
33 "flexAPICreditUnit": 50000,
34 "flexModeratorCostCents": 500,
35 "flexModeratorUnit": 1,
36 "flexAdminCostCents": 1000,
37 "flexAdminUnit": 1,
38 "flexDomainCostCents": 1000,
39 "flexDomainUnit": 1,
40 "flexMinimumCostCents": 99
41}'
42
TenantPackage Create Request Structure
Copy Copy
1
2interface TenantPackagePostQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
TenantPackage Create Response Structure
Copy Copy
1
2interface TenantPackagePostResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'unexpected-param' | 'not-found' 'white-labeling-not-allowed' | 'name-too-long' | 'for-who-text-too-long' | 'feature-tag-lines-too-long' | 'no-package' | 'invalid-package' | 'unauthorized' | 'child-tenant-too-large' | 'flex-param-missing' | 'unexpected-flex-param' | 'package-limit-reached' | 'flex-param-missing' | 'unexpected-flex-param'
6 /** Included on failure. **/
7 reason?: string
8 tenantPackage?: TenantPackage; // We return the complete created tenant package on success.
9}
10

PATCH /api/v1/tenant-packages/:id Internal Link

Resource: TenantPackage as PATCH /api/v1/tenant-packages/:id Credit Cost: 1

This API endpoint provides the ability to update a TenantPackage by id.

Updating a TenantPackage has the following restrictions:

  • If you are setting hasFlexPricing to true, then all flex* parameters are required in that same request.
  • The name may not be longer than 50 characters.
  • Each forWhoText item may not be longer than 200 characters.
  • Each featureTaglines item may not be longer than 100 characters.
  • The TenantPackage must be "smaller" than the parent tenant. For example, all of the max* parameters must have lower values than the parent tenant.
  • You may not change the tenantId associated with a TenantPackage.
TenantPackage PATCH cURL Example
Copy Copy
1
2curl --request PATCH \
3 --url 'https://fastcomments.com/api/v1/tenant-packages/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "name": "Some New Name",
7}'
8
TenantPackage PATCH Request Structure
Copy Copy
1
2interface TenantPackagePatchQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
TenantPackage PATCH Response Structure
Copy Copy
1
2
3interface TenantPackagePatchResponse {
4 status: 'success' | 'failed'
5 /** Included on failure. **/
6 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'unexpected-param' | 'not-found' | 'white-labeling-not-allowed' | 'name-too-long' | 'for-who-text-too-long' | 'feature-tag-lines-too-long' | 'no-package' | 'invalid-package' | 'unauthorized' | 'child-tenant-too-large' | 'flex-param-missing' | 'unexpected-flex-param' | 'package-limit-reached' | 'flex-param-missing' | 'unexpected-flex-param';
7 /** Included on failure. **/
8 reason?: string
9}
10

DELETE /api/v1/tenant-packages/:id Internal Link

Resource: TenantPackage as DELETE /api/v1/tenant-packages/:id Credit Cost: 5

This route provides the removal of a TenantPackage by id.

You may not remove a TenantPackage that is in use (a tenant's packageId points to the package). Update the Tenant first.

TenantPackage Removal cURL Example
Copy Copy
1
2curl --request DELETE \
3 --url 'https://fastcomments.com/api/v1/tenant-packages/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
TenantPackage Removal Request Structure
Copy Copy
1
2interface TenantPackageDeleteQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
TenantPackage Removal Response Structure
Copy Copy
1
2interface TenantPackageDeleteResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'not-found' | 'unauthorized' | 'package-in-use'
6 /** Included on failure. **/
7 reason?: string
8}
9

Tenant User Structure Internal Link

The TenantUser defines a User which is managed by a specific tenant. Their account is in complete control of the tenant they are associated with, and their account can be updated or deleted via the UI or API.

Tenant users can be administrators with all permissions and access to the Tenant, or they can be limited to specific permissions to moderate comments, access API keys, etc.

The structure for the TenantUser object is as follows:

TenantUser Structure
Copy Copy
1
2/** This is for notifications. **/
3export enum UserDigestEmailFrequency {
4 Disabled = -1,
5 Daily = 0,
6 Weekly = 1,
7 Monthly = 2
8}
9
10export interface TenantUser {
11 id: string
12 tenantId: string
13 username: string
14 /** A link to the commenter's blog, for example. **/
15 websiteUrl?: string
16 email: string
17 signUpDate: number
18 createdFromUrlId: string
19 createdFromTenantId: string
20 verified: boolean
21 loginCount: number
22 optedInNotifications: boolean
23 optedInTenantNotifications: boolean
24 hideAccountCode: boolean
25 avatarSrc?: string
26 /** Does the user receive help requests from commenters? **/
27 isHelpRequestAdmin: boolean
28 isAccountOwner: boolean
29 isAdminAdmin: boolean
30 isBillingAdmin: boolean
31 isAnalyticsAdmin: boolean
32 isCustomizationAdmin: boolean
33 isManageDataAdmin: boolean
34 isCommentModeratorAdmin: boolean
35 isAPIAdmin: boolean
36 moderatorIds: string[]
37 locale: FastCommentsLocale
38 digestEmailFrequency: UserDigestEmailFrequency
39 lastLoginDate: string
40 displayLabel?: string
41}
42

GET /api/v1/tenant-users/:id Internal Link

Resource: TenantUser as GET /api/v1/tenant-users/:id Credit Cost: 1

This route returns a single TenantUser by id.

TenantUser By ID cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/tenant-users/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
TenantUser Request Structure
Copy Copy
1
2interface TenantUserByIdQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
TenantUser Response Structure
Copy Copy
1
2interface TenantUserByIdResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-id' | 'not-found' | 'unauthorized'
6 /** Included on failure. **/
7 reason?: string
8 tenantUser?: TenantUser
9}
10

GET /api/v1/tenant-users Internal Link

Resource: TenantUser as GET /api/v1/tenant-users Credit Cost: 1

This API uses pagination, provided by the skip query parameter. TenantUsers are returned in pages of 100, ordered by signUpDate, username and id.

The cost is based on the number of tenant users returned, costing 1 credit per 10 tenant users returned.

TenantUser cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/tenant-users?tenantId=demo&page=0&API_KEY=DEMO_API_SECRET'
4
TenantUser Request Structure
Copy Copy
1
2interface TenantUsersRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** The number of tenant users to skip for pagination. **/
6 skip?: number
7}
8
TenantUser Response Structure
Copy Copy
1
2interface TenantUsersResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key'
6 /** Included on failure. **/
7 reason?: string
8 tenantUsers?: TenantUser[]
9}
10

POST /api/v1/tenant-users Internal Link

Resource: TenantUser as POST /api/v1/tenant-users Credit Cost: 1

This route provides the ability to add a single TenantUser.

Creating a TenantUser has the following restrictions:

  • A username is required.
  • A email is required.
  • The signUpDate may not be in the future.
  • The locale must be in the list of Supported Locales.
  • The username must be unique across all of FastComments.com. If this is an issue, we suggest using SSO instead.
  • The email must be unique across all of FastComments.com. If this is an issue, we suggest using SSO instead.
  • You may not create more tenant users than defined under maxTenantUsers in your package.

We can create a TenantUser as follows

TenantUser Create cURL Example
Copy Copy
1
2curl --request POST \
3 --url 'https://fastcomments.com/api/v1/tenants?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "username": "Some Name",
7 "email": "someone@someone.com"
8}'
9
TenantUser Create Request Structure
Copy Copy
1
2interface TenantUserPostQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
TenantUser Create Response Structure
Copy Copy
1
2interface TenantUserPostResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'username-required' | 'email-required' | 'sign-up-date-in-future' | 'unsupported-locale' | 'unauthorized' | 'username-taken' | 'email-taken' | 'tenant-user-limit-reached'
6 /** Included on failure. **/
7 reason?: string
8 tenantUser?: TenantUser; // We return the complete created tenant user on success.
9}
10
Resource: TenantUser as POST /api/v1/tenant-users/:id/send-login-link Credit Cost: 10

This route provides the ability to send a login link to a single TenantUser.

Useful when batch creating users and not having to instruct them on how to login to FastComments.com. This will just send them a "magic link" to login that expires after 30 days.

The following restrictions exist to send a login link to a TenantUser:

  • The TenantUser must already exist.
  • You must have access to manage the Tenant the TenantUser belongs to.

We can send a login link to a TenantUser as follows:

TenantUser Login Link cURL Example
Copy Copy
1
2curl --request POST \
3 --url 'https://fastcomments.com/api/v1/tenant-users/xyz/send-login-link?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json'
5

This will send an email like Bob at TenantName is inviting you to be a moderator...

TenantUser Login Link Request Structure
Copy Copy
1
2interface TenantUserPostQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
TenantUser Login Link Response Structure
Copy Copy
1
2interface TenantUserPostResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'unauthorized' | 'not-found'
6 /** Included on failure. **/
7 reason?: string
8}
9

PATCH /api/v1/tenant-users/:id Internal Link

Resource: TenantUser as PATCH /api/v1/tenant-users/:id Credit Cost: 1

This route provides the ability to update a single TenantUser.

Updating a TenantUser has the following restrictions:

  • The signUpDate may not be in the future.
  • The locale must be in the list of Supported Locales.
  • The username must be unique across all of FastComments.com. If this is an issue, we suggest using SSO instead.
  • The email must be unique across all of FastComments.com. If this is an issue, we suggest using SSO instead.
  • You cannot update the tenantId of a user.

We can create a TenantUser as follows

TenantUser Update cURL Example
Copy Copy
1
2curl --request PATCH \
3 --url 'https://fastcomments.com/api/v1/tenant-users/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "username": "Some Name",
7 "email": "someone@someone.com"
8}'
9
TenantUser Update Request Structure
Copy Copy
1
2interface TenantUserPatchQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** When email or username is changed, you can set this to true to also update the user's comments. This will double the credit cost. **/
6 updateComments: 'true' | 'false'
7}
8
TenantUser Update Response Structure
Copy Copy
1
2interface TenantUserPatchResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'sign-up-date-in-future' | 'unsupported-locale' | 'unauthorized' | 'username-taken' | 'email-taken' | 'unauthorized' | 'no-package' | 'invalid-package' | 'tenant-user-limit-reached' | 'user-does-not-exist'
6 /** Included on failure. **/
7 reason?: string
8}
9

DELETE /api/v1/tenant-users/:id Internal Link

Resource: TenantUser as DELETE /api/v1/tenant-users/:id Credit Cost: 5

This route provides the removal of a TenantUser by id.

TenantUser Removal cURL Example
Copy Copy
1
2curl --request DELETE \
3 --url 'https://fastcomments.com/api/v1/tenant-users/xyz?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
TenantUser Removal Request Structure
Copy Copy
1
2interface TenantUserDeleteQueryParams {
3 tenantId: string
4 API_KEY: string
5 /** You can set this to true to also delete the user's comments. This will double the credit cost. **/
6 deleteComments: 'true' | 'false'
7}
8
TenantUser Removal Response Structure
Copy Copy
1
2interface TenantUserDeleteResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'not-found' | 'unauthorized'
6 /** Included on failure. **/
7 reason?: string
8}
9

Vote Structure Internal Link

A Vote object represents a vote left by a user.

The relationship between comments and vote is defined via commentId.

The structure for the Vote object is as follows:

Vote Structure
Copy Copy
1
2interface Vote {
3 id: string
4 urlId: string
5 commentId: string
6 userId: string
7 direction: 1 | -1
8 createdAt: string
9}
10

GET /api/v1/votes Internal Link

Resource: Vote as GET /api/v1/votes Credit Cost: 10

Votes must be fetched by urlId.

Types of Votes

There are three types of votes:

  • Authenticated Votes, which are applied to the corresponding comment. You can create these via this API.
  • Authenticated Votes, which are pending verification, and thus are not yet applied to the comment. These are created when a user uses the FastComments.com login to vote mechanism.
  • Anonymous Votes, which are applied to the corresponding comment. These are created along with anonymous commenting.

These are returned in separate lists in the API to reduce confusion.

Votes cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/votes?tenantId=demo&API_KEY=DEMO_API_SECRET&urlId=test'
4
Votes Request Structure
Copy Copy
1
2interface VotesRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5 urlId: string
6}
7
Votes Response Structure
Copy Copy
1
2interface VotesResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-url-id'
6 /** Included on failure. **/
7 reason?: string
8 /** Authorized, verified votes, applied to their corresponding comments. **/
9 appliedAuthorizedVotes: Vote[]
10 /** Anonymous votes, applied to their corresponding comments. **/
11 appliedAnonymousVotes: Vote[]
12 /** Votes pending verification, not yet applied to their corresponding comments. **/
13 pendingVotes: Vote[]
14}
15

GET /api/v1/votes/for-user Internal Link

Resource: Vote as GET /api/v1/votes/for-user Credit Cost: 1

Allows fetching votes left by a user on a given urlId. Takes a userId which can be any FastComments.com or SSO User.

This is useful if you want to show if a user has voted on a comment. When fetching comments, simply call this API at the same time for the user with the same urlId.

Votes For User cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/votes/for-user?tenantId=demo&API_KEY=DEMO_API_SECRET&urlId=test&userId=some-user-id'
4
Votes For User Request Structure
Copy Copy
1
2interface VotesForUserRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5 urlId: string
6 userId: string
7}
8
Votes For User Response Structure
Copy Copy
1
2interface VotesForUserResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-url-id' | 'invalid-user-id'
6 /** Included on failure. **/
7 reason?: string
8 /** Authorized, verified votes, applied to their corresponding comments. **/
9 appliedAuthorizedVotes: Vote[]
10 /** Votes pending verification, not yet applied to their corresponding comments. **/
11 pendingVotes: Vote[]
12}
13

POST /api/v1/votes Internal Link

Resource: Vote as POST /api/v1/votes Credit Cost: 1

This route provides the ability to add a single authorized Vote. Votes can be up (+1) or down (-1).

Vote Create cURL Example
Copy Copy
1
2curl --request POST \
3 --url 'https://fastcomments.com/api/v1/votes?tenantId=demo&API_KEY=DEMO_API_SECRET&userId=user-id&commentId=comment-id&direction=up' \
4 --header 'Content-Type: application/json'
5
Vote Create Request Structure
Copy Copy
1
2interface VotePostQueryParams {
3 tenantId: string
4 API_KEY: string
5 userId: string
6 commentId: string
7 direction: 'up' | 'down'
8}
9
Vote Create Response Structure
Copy Copy
1
2interface VotePostResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-user-id' | 'invalid-user-id' | 'invalid-comment-id' | 'invalid-direction' | 'duplicate' | 'voting-disabled'
6 /** Included on failure. **/
7 reason?: string
8 voteId?: string
9}
10

Notes:

  • This API obeys tenant-level settings. For example, if you disable voting for a given page, and you attempt to create a vote via the API, it will fail with error code voting-disabled.
  • This API is live by default.
  • This API will update the votes of the corresponding Comment.

DELETE /api/v1/votes/:id Internal Link

Resource: Vote as DELETE /api/v1/votes/:id Credit Cost: 1

This route provides the ability to delete a single Vote.

Vote Delete cURL Example
Copy Copy
1
2curl --request DELETE \
3 --url 'https://fastcomments.com/api/v1/votes/some-id?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json'
5
Vote Delete Request Structure
Copy Copy
1
2interface VoteDeleteQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Vote Delete Response Structure
Copy Copy
1
2interface VoteDeleteResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-id'
6 /** Included on failure. **/
7 reason?: string
8}
9

Notes:

  • This API obeys tenant-level settings. For example, if you disable voting for a given page, and you attempt to create a vote via the API, it will fail with error code voting-disabled.
  • This API is live by default.
  • This API will update the votes of the corresponding Comment.

DomainConfig Structure Internal Link

A DomainConfig object represents configuration for a domain for a tenant.

The structure for the DomainConfig object is as follows:

Domain Config Structure
Copy Copy
1
2interface DomainConfig {
3 /** A domain, not a URL, like "fastcomments.com" or "www.example.com". Subdomain may be included if limiting to a subdomain is desired. Max 1000 characters. **/
4 domain: string
5 /** The From-Name used when sending emails. **/
6 emailFromName?: string
7 /** The From-Email used when sending emails. Ensure SPF is setup to allow mail.fastcomments.com to send emails as the domain used in this attribute. **/
8 emailFromEmail?: string
9 /** READONLY. When the object was created. **/
10 createdAt: string
11 /** The logo related to this domain. Used in emails. Use HTTPS. **/
12 logoSrc?: string
13 /** A smaller logo related to this domain. Use HTTPS. **/
14 logoSrc100px?: string
15 /** SSO ONLY. The URL used in the footer of every email sent. Supports a "[userId]" variable. **/
16 footerUnsubscribeURL?: string
17 /** SSO ONLY. The headers used in of every email sent. Useful for example for setting unsubscribe related headers to improve delivery. The List-Unsubscribe entry in this Record, if it exists, supports a "[userId]" variable. **/
18 emailHeaders?: Record<string, string>
19 /** Disable all unsubscribe links. Not recommended, may hurt delivery rates. **/
20 disableUnsubscribeLinks?: boolean
21 /** DKIM Configuration. **/
22 dkim?: DomainConfigDKIM
23}
24
DKIM Config Structure
Copy Copy
1
2interface DomainConfigDKIM {
3 /** The domain name in your DKIM record. **/
4 domainName: string
5 /** The DKIM key selector to use. **/
6 keySelector: string
7 /** Your private key. Start with -----BEGIN PRIVATE KEY----- and end with -----END PRIVATE KEY----- **/
8 privateKey: string
9}
10

For Authentication

Domain Configuration is used to determine which sites can host the FastComments widget for your account. This is a basic form of authentication, meaning adding or removing any Domain Configurations can impact the availability of your FastComments installation in production.

Don't remove or update the domain property of a Domain Config for a domain that is currently in use unless disabling that domain is intended.

This has the same behavior as removing a domain from /auth/my-account/configure-domains.

Also note that removing a domain from the My Domains UI will remove any corresponding configuration for that domain that may have been added via this UI.

For Email Customization

The unsubscribe link in the email footer, and the one-click-unsubscribe feature offered by many email clients, can be configured via this API by defining footerUnsubscribeURL and emailHeaders, respectively.

For DKIM

After defining your DKIM DNS records, simply update the DomainConfig with your DKIM configuration using the defined structure.

GET /api/v1/domain-configs Internal Link

Resource: Comment as GET /api/v1/domain-configs Credit Cost: 1

This API provides the ability to fetch all DomainConfig objects for a tenant.

DomainConfig GET cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/domain-configs?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
DomainConfig GET Request Structure
Copy Copy
1
2interface GetDomainConfigsRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
DomainConfig GET Response Structure
Copy Copy
1
2interface GetDomainConfigsResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key'
6 /** Included on failure. **/
7 reason?: string
8 /** The configurations! **/
9 configurations: DomainConfig[] | null
10}
11

GET /api/v1/domain-configs/:domain Internal Link

Resource: DomainConfig as GET /api/v1/domain-configs/:domain Credit Cost: 1

Individual DomainConfigs can be fetched by their corresponding domain.

Domain Config by Domain cURL Example
Copy Copy
1
2curl --request GET \
3 --url 'https://fastcomments.com/api/v1/domain-configs/example.com?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
Domain Config by Domain Request Structure
Copy Copy
1
2interface DomainConfigsByDomainRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
Domain Config by Domain Response Structure
Copy Copy
1
2interface DomainConfigResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'internal' | 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-url-id' | 'missing-domain' | 'update-would-create-duplicate' | 'domain-does-not-exist'
6 /** Included on failure. **/
7 reason?: string
8 configuration?: DomainConfig | null
9}
10

POST /api/v1/domain-configs Internal Link

Resource: DomainConfig as POST /api/v1/domain-configs Credit Cost: 1

This API endpoint provides the ability to create domain configurations.

Adding configuration for a domain authorizes that domain for the FastComments account.

Common use cases of this API are initial setup, if many domains are desired to be added, or custom configuration for sending emails.

DomainConfig POST cURL Example
Copy Copy
1
2curl --request POST \
3 --url 'https://fastcomments.com/api/v1/domain-configs?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "domain": "example.com",
7 "emailFromName": "some from name",
8 "emailFromEmail": "some@test.com",
9 "logoSrc": "https://example.com/my-logo-big.png",
10 "logoSrc100px": "https://example.com/my-logo-100px.png",
11 "footerUnsubscribeURL": "http://example.com/unsubscribe-ui",
12 "emailHeaders": {
13 "List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
14 "List-Unsubscribe": "<https://example.com/opt-out/[userId]>"
15 }
16}'
17
DomainConfig POST Request Structure
Copy Copy
1
2interface DomainConfigPostQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
DomainConfig POST Response Structure
Copy Copy
1
2
3interface DomainConfigPostResponse {
4 status: 'success' | 'failed'
5 /** Included on failure. **/
6 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'empty-request' | 'internal' | 'invalid-input' | 'missing-domain' | 'configuration-exists-for-domain' | 'domain-too-long' | 'domain-invalid';
7 /** Included on failure. **/
8 reason?: string
9 /** The created configuration. **/
10 configuration?: DomainConfig
11}
12

PATCH /api/v1/domain-configs/:domain Internal Link

Resource: DomainConfig as PATCH /api/v1/domain-configs/:domain Credit Cost: 1

This API endpoint provides the ability to update a domain configuration by only specifying the domain and the attribute to update.

DomainConfig PATCH cURL Example
Copy Copy
1
2curl --request PATCH \
3 --url 'https://fastcomments.com/api/v1/domain-configs/example.com?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "emailFromName": "Some New From Name",
7}'
8
DomainConfig PATCH Request Structure
Copy Copy
1
2interface DomainConfigPatchQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
DomainConfig PATCH Response Structure
Copy Copy
1
2
3interface DomainConfigPatchResponse {
4 status: 'success' | 'failed'
5 /** Included on failure. **/
6 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'empty-request' | 'internal' | 'invalid-input' | 'missing-domain' | 'domain-does-not-exist' | 'update-would-create-duplicate' | 'domain-too-long' | 'domain-invalid';
7 /** Included on failure. **/
8 reason?: string
9 /** The updated configuration. **/
10 configuration?: DomainConfig
11}
12

PUT /api/v1/domain-configs/:domain Internal Link

Resource: DomainConfig as PUT /api/v1/domain-configs/:domain Credit Cost: 1

This API endpoint provides the ability to replace a domain configuration.

DomainConfig PUT cURL Example
Copy Copy
1
2curl --request PUT \
3 --url 'https://fastcomments.com/api/v1/domain-configs/example.com?tenantId=demo&API_KEY=DEMO_API_SECRET' \
4 --header 'Content-Type: application/json' \
5 --data '{
6 "domain": "new-domain-example.com",
7 "emailFromName": "some from name",
8 "emailFromEmail": "some@test.com",
9 "logoSrc": "https://example.com/my-logo-big.png",
10 "logoSrc100px": "https://example.com/my-logo-100px.png",
11 "footerUnsubscribeURL": "http://example.com/unsubscribe-ui",
12 "emailHeaders": {
13 "List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
14 "List-Unsubscribe": "<https://example.com/opt-out/[userId]>"
15 }
16}'
17
DomainConfig PUT Request Structure
Copy Copy
1
2interface DomainConfigPutQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
DomainConfig PUT Response Structure
Copy Copy
1
2
3interface DomainConfigPutResponse {
4 status: 'success' | 'failed'
5 /** Included on failure. **/
6 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'empty-request' | 'internal' | 'invalid-input' | 'missing-domain' | 'domain-does-not-exist' | 'update-would-create-duplicate' | 'domain-too-long' | 'domain-invalid';
7 /** Included on failure. **/
8 reason?: string
9 /** The updated configuration. **/
10 configuration?: DomainConfig
11}
12

DELETE /api/v1/domain-configs/:domain Internal Link

Resource: DomainConfig as DELETE /api/v1/domain-configs/:domain Credit Cost: 1

This route provides the removal of a single DomainConfig by id.

  • Note: Removing a DomainConfig will un-authorize that domain from using FastComments.
  • Note: Re-adding a domain via the UI will recreate the object (with just domain populated).
DomainConfig Removal cURL Example
Copy Copy
1
2curl --request DELETE \
3 --url 'https://fastcomments.com/api/v1/domain-configs/example.com?tenantId=demo&API_KEY=DEMO_API_SECRET'
4
DomainConfig Removal Request Structure
Copy Copy
1
2interface DomainConfigRequestQueryParams {
3 tenantId: string
4 API_KEY: string
5}
6
DomainConfig Removal Response Structure
Copy Copy
1
2interface DomainConfigDeleteResponse {
3 status: 'success' | 'failed'
4 /** Included on failure. **/
5 code?: 'missing-tenant-id' | 'invalid-tenant-id' | 'invalid-api-key' | 'missing-api-key' | 'missing-domain' | 'domain-config-does-not-exist'
6 /** Included on failure. **/
7 reason?: string
8}
9

In Conclusion

We hope you've found our API documentation thorough and easy to understand. If you find any gaps, let us know below.