Back to arky.io

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

POST /v1/businesses/{businessId}/reactions
SDK: 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

GET /v1/businesses/{businessId}/reactions/{id}
SDK: sdk.reaction.get()

Find Reactions

GET /v1/businesses/{businessId}/reactions
SDK: 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

PUT /v1/businesses/{businessId}/reactions/{id}
SDK: sdk.reaction.update()

Update the content of a reaction (e.g. edit a review). Target and kind are immutable.

Delete Reaction

DELETE /v1/businesses/{businessId}/reactions/{id}
SDK: sdk.reaction.remove()

Moderate Reaction (Admin)

POST /v1/businesses/{businessId}/reactions/{id}/moderate
SDK: 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)

GET /v1/businesses/{businessId}/reactions/admin
SDK: sdk.reaction.listAdmin()

Admin listing across an entire business, including pending and hidden reactions.

Engagement Summary

GET /v1/businesses/{businessId}/reactions/summary
SDK: 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.