Skip to content
Linq Copy agent prompt

Add or remove a reaction to a message

client.Messages.AddReaction(ctx, messageID, body) (*MessageAddReactionResponse, error)
POST/v3/messages/{messageId}/reactions

Add or remove emoji reactions to messages. Reactions let users express their response to a message without sending a new message.

Supported Reactions:

  • love ❤️
  • like 👍
  • dislike 👎
  • laugh 😂
  • emphasize ‼️
  • question ❓
  • custom - any emoji as a tapback (use custom_emoji field to specify)
  • sticker - an emoji or image peeled onto the message (use emoji, url or attachment_id)

custom and sticker are different products. A custom reaction is a tapback: the emoji sits in a small bubble on the corner of the message. A sticker is peeled onto the bubble itself, and can be dragged, resized and rotated. Both accept an emoji; they do not look alike.

Stickers are iMessage-only and cannot be removed, so operation: "remove" with type: "sticker" is rejected. Position, size and rotation are optional via placement, and can be changed afterwards with PATCH /v3/messages/{messageId}/reactions/{reactionId}. An animated image peels as an animated sticker, in whatever shape the file already has.

Polls take stickers only. Any tapback on a poll message — standard or custom — is rejected with a 400.

ParametersExpand Collapse
messageID string
formatuuid
body MessageAddReactionParams
Operation param.Field[MessageAddReactionParamsOperation]

Whether to add or remove the reaction

const MessageAddReactionParamsOperationAdd MessageAddReactionParamsOperation = "add"
const MessageAddReactionParamsOperationRemove MessageAddReactionParamsOperation = "remove"
Type param.Field[ReactionType]

Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type “custom” with the actual emoji in the custom_emoji field. Sticker reactions have type “sticker” with sticker attachment details in the sticker field.

AttachmentID param.Field[string]Optional

Reference to a sticker image pre-uploaded via POST /v3/attachments. Only valid when type is “sticker”.

Exactly one of emoji, url or attachment_id is required when type is “sticker”.

formatuuid
CustomEmoji param.Field[string]Optional

Custom emoji string. Required when type is “custom”.

This is a tapback — the emoji sits in the tapback bubble on the corner of the message. To peel an emoji onto the message as a draggable sticker instead, use type “sticker” with emoji.

Emoji param.Field[string]Optional

A single emoji to peel onto the message as a sticker. Only valid when type is “sticker”.

Exactly one of emoji, url or attachment_id is required when type is “sticker”.

Not to be confused with custom_emoji, which produces a tapback.

maxLength64
PartIndex param.Field[int64]Optional

Optional index of the message part to react to. If not provided, reacts to the entire message (part 0).

Placement param.Field[MessageAddReactionParamsPlacement]Optional

Optional position, size and rotation of a sticker on the target bubble. Only valid when type is “sticker”.

Every field is independent and optional — omit the object entirely, or any field within it, to keep the default (centred, default size, unrotated).

Rotation float64Optional

Clockwise rotation in degrees.

formatdouble
minimum-180
maximum180
Scale float64Optional

How large the sticker is drawn. Omit it for the default size — equivalent to 1 for an image, or 0.5 for an emoji.

Values outside 0.05–2.5 are clamped rather than rejected.

Scale is linear, so 2.5 is a little over six times the area.

formatdouble
minimum0.05
maximum2.5
X float64Optional

Horizontal position on the target bubble, from -1 (far left) to 1 (far right). 0 is centred.

formatdouble
minimum-1
maximum1
Y float64Optional

Vertical position on the target bubble, from -1 (top) to 1 (bottom). 0 is centred.

formatdouble
minimum-1
maximum1
URL param.Field[string]Optional

Linq attachment URL of the sticker image — the download_url returned by POST /v3/attachments. Only valid when type is “sticker”.

The image must already be stored with us. To send a sticker from elsewhere, upload it with POST /v3/attachments first and pass attachment_id.

Exactly one of emoji, url or attachment_id is required when type is “sticker”.

formaturi
ReturnsExpand Collapse
type MessageAddReactionResponse struct{…}
Message stringOptional
Status stringOptional
TraceID stringOptional

Add or remove a reaction to a message

package main

import (
  "context"
  "fmt"

  "github.com/linq-team/linq-go"
  "github.com/linq-team/linq-go/option"
  "github.com/linq-team/linq-go/shared"
)

func main() {
  client := linqgo.NewClient(
    option.WithAPIKey("My API Key"),
  )
  response, err := client.Messages.AddReaction(
    context.TODO(),
    "69a37c7d-af4f-4b5e-af42-e28e98ce873a",
    linqgo.MessageAddReactionParams{
      Operation: linqgo.MessageAddReactionParamsOperationAdd,
      Type: shared.ReactionTypeLove,
    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", response.TraceID)
}
{
  "message": "Reaction processed",
  "status": "accepted",
  "trace_id": "trace_id"
}
{
  "error": {
    "status": 400,
    "code": 1002,
    "message": "Phone number must be in E.164 format",
    "doc_url": "https://docs.linqapp.com/channel/imessage/error/codes/1xxx/1002/"
  },
  "success": false
}
{
  "error": {
    "status": 401,
    "code": 2004,
    "message": "Unauthorized - missing or invalid authentication token",
    "doc_url": "https://docs.linqapp.com/channel/imessage/error/codes/2xxx/2004/"
  },
  "success": false
}
{
  "error": {
    "status": 403,
    "code": 2005,
    "message": "Access denied - insufficient permissions for this resource",
    "doc_url": "https://docs.linqapp.com/channel/imessage/error/codes/2xxx/2005/"
  },
  "success": false
}
{
  "error": {
    "status": 500,
    "code": 3006,
    "message": "Internal server error",
    "doc_url": "https://docs.linqapp.com/channel/imessage/error/codes/3xxx/3006/"
  },
  "success": false
}
Returns Examples
{
  "message": "Reaction processed",
  "status": "accepted",
  "trace_id": "trace_id"
}
{
  "error": {
    "status": 400,
    "code": 1002,
    "message": "Phone number must be in E.164 format",
    "doc_url": "https://docs.linqapp.com/channel/imessage/error/codes/1xxx/1002/"
  },
  "success": false
}
{
  "error": {
    "status": 401,
    "code": 2004,
    "message": "Unauthorized - missing or invalid authentication token",
    "doc_url": "https://docs.linqapp.com/channel/imessage/error/codes/2xxx/2004/"
  },
  "success": false
}
{
  "error": {
    "status": 403,
    "code": 2005,
    "message": "Access denied - insufficient permissions for this resource",
    "doc_url": "https://docs.linqapp.com/channel/imessage/error/codes/2xxx/2005/"
  },
  "success": false
}
{
  "error": {
    "status": 500,
    "code": 3006,
    "message": "Internal server error",
    "doc_url": "https://docs.linqapp.com/channel/imessage/error/codes/3xxx/3006/"
  },
  "success": false
}