Reactions
Likes, ratings, comments, and reviews on products, services, providers, bookings, and CMS nodes
The Reactions module lets customers engage with content: likes, emoji reactions, star ratings, comments, and reviews. Any reaction is attached to a target — a product, service, provider, booking, or CMS node — and can optionally be nested under a parent reaction (threaded replies).
Key Concepts
Target
Every reaction points at a single target:
type ReactionTargetType = 'product' | 'service' | 'provider' | 'booking' | 'node';
interface ReactionTarget {
type: ReactionTargetType;
id: string;
}
Kind
The kind field is a free-form lowercase slug describing what the reaction is. Kinds must match /^[a-z0-9_]{1,32}$/.
Built-in kinds (DEFAULT_REACTION_KINDS):
like, love, laugh, wow, sad, insightful,
review, comment,
star_1, star_2, star_3, star_4, star_5
You can use any custom kind that matches the regex. Use isValidReactionKind(kind) to validate.
Blocks
Reactions use the same blocks content model as the rest of the platform, so a comment or review can carry rich text, images, and any other block type.
Status and Moderation
Reactions have a lifecycle status: pending, published, hidden, removed. Moderation endpoints let admins transition status.
Endpoints
Create Reaction
/v1/businesses/{businessId}/reactions sdk.reaction.create() Creates a reaction on a target. Works for both authenticated customers and anonymous (via the customer session token).
Parameters
| Name | Type | Description |
|---|---|---|
target required | ReactionTarget | The target object this reaction is attached to |
kind required | string | Reaction kind (e.g. like, star_5, review, comment) |
blocks optional | Block[] | Optional rich content (used by reviews, comments) |
parentId optional | string | Parent reaction ID for threaded replies |
taxonomies optional | TaxonomyEntry[] | Optional taxonomy entries |
Get Reaction
/v1/businesses/{businessId}/reactions/{id} sdk.reaction.get() Find Reactions
/v1/businesses/{businessId}/reactions sdk.reaction.find() List and filter reactions. Supports filtering by target, customer, kind, parent (for threaded replies), and status.
Parameters
| Name | Type | Description |
|---|---|---|
targetType optional | ReactionTargetType | Filter by target type |
targetId optional | string | Filter by target ID |
parentId optional | string | Filter replies under a parent reaction |
customerId optional | string | Filter by customer ID |
kind optional | string | Filter by reaction kind |
status optional | ReactionStatus | pending, published, hidden, or removed |
contentOnly optional | boolean | Only return reactions that carry blocks (e.g. review, comment) |
query optional | string | Full-text search over reaction content |
limit optional | number | Items per page |
cursor optional | string | Pagination cursor |
Update Reaction
/v1/businesses/{businessId}/reactions/{id} sdk.reaction.update() Update the content of a reaction (e.g. edit a review). Target and kind are immutable.
Delete Reaction
/v1/businesses/{businessId}/reactions/{id} sdk.reaction.remove() Moderate Reaction (Admin)
/v1/businesses/{businessId}/reactions/{id}/moderate sdk.reaction.moderate() Transition a reaction to a new status. Use to publish a pending review, hide spam, or reinstate a hidden reaction.
Parameters
| Name | Type | Description |
|---|---|---|
id required | string | Reaction ID |
status required | ReactionStatus | New status: pending, published, hidden, removed |
List Reactions (Admin)
/v1/businesses/{businessId}/reactions/admin sdk.reaction.listAdmin() Admin listing across an entire business, including pending and hidden reactions.
Engagement Summary
/v1/businesses/{businessId}/reactions/summary sdk.reaction.summary() Returns aggregate counts of reactions by kind for a target, plus any reactions the current customer has left on it. Use this to render like buttons, star averages, and “you already reviewed” states in one call.
Parameters
| Name | Type | Description |
|---|---|---|
targetType required | ReactionTargetType | Target type to summarize |
targetId required | string | Target ID to summarize |
parentId optional | string | Summarize replies under a specific parent |
Reaction Object
{
"id": "rx_abc",
"businessId": "biz_abc",
"customerInfo": { "id": "cust_abc", "verified": true },
"target": { "type": "product", "id": "prod_abc" },
"parentId": null,
"kind": "star_5",
"blocks": [],
"taxonomies": [],
"status": "published",
"createdAt": 1234567890,
"updatedAt": 1234567890
}
Helpers
The SDK exports a few helpers from the reaction module:
import {
DEFAULT_REACTION_KINDS,
REACTION_KIND_REGEX,
isValidReactionKind,
computeAverageStars,
} from '@arky/sdk';
isValidReactionKind('star_5'); // true
isValidReactionKind('Star Five'); // false
// Compute a 1-5 star average from a counts map
computeAverageStars({ star_1: 1, star_4: 4, star_5: 5 });
// { average: 4.4, count: 10 }
computeAverageStars and isValidReactionKind are also attached to the API object itself, so you can call sdk.reaction.computeAverageStars(...) directly.