Skip to content

Add an activity to a feed

POST
/v1/feeds/{group}/{id}/activities
curl --request POST \
--url http://localhost:3000/v1/feeds/example/example/activities \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "actor": "example", "verb": "example", "object": "example", "target": "example", "foreign_id": "example", "time": "2026-04-15T12:00:00Z", "custom": {}, "refs": [ "example" ] }'
group
required
string
id
required
string
Media typeapplication/json
object
actor

Ignored and overwritten for user tokens (spec §5).

string
verb
required
string
object
required
string
target
string | null
foreign_id

Requires time when present — VALIDATION_FAILED otherwise. Dedupe is on the (foreign_id, time) pair; a foreign_id without a caller-pinned time can never dedupe (each retry would get a fresh server timestamp, silently duplicating), so the API rejects the combination rather than letting an idempotency assumption fail quietly. Deliberate safety deviation from GetStream.

string | null
time

For user tokens, clamped to [now - 10 min, now] (spec §5): retries with the same (foreign_id, time) dedupe; future-pinning is impossible. Server tokens pass it through unclamped. Required when foreign_id is set.

string format: date-time
custom
object
key
additional properties
any
refs

Objects this activity points at, as type:id. Max 4, no duplicates.

Array<string>
Examplegenerated
{
"actor": "example",
"verb": "example",
"object": "example",
"target": "example",
"foreign_id": "example",
"time": "2026-04-15T12:00:00Z",
"custom": {},
"refs": [
"example"
]
}

Created — or, on a (foreign_id, time) duplicate of a live activity, the existing row unchanged (idempotent, no second fan-out).

Media typeapplication/json
object
id
required
string format: uuid
actor
required
string
verb
required
string
object
required
string
target
string | null
foreign_id
string | null
time
required
string format: date-time
custom
required
object
key
additional properties
any
origin_feed
required
string
reaction_counts
required
object
key
additional properties
integer
comment_count
required
integer
actor_user

Enriched from users.custom when actor parses as user:. Null otherwise.

object | null
own_reactions

Omitted for server tokens — no caller identity.

Array<string>
refs
required

Objects this activity points at, as type:id. Resolved into the feed read’s objects sidecar. Max 4, no duplicates.

Array<string>
edited_at
required

Null until the activity is first patched.

string | null format: date-time
version
required

Row version. Starts at 1 and increments on ANY change to this activity — a patch, a reaction count moving, a soft delete. Compare it against the copy you hold to decide whether to re-render; edited_at marks patches only, so it cannot report the field that changes most.

integer
warnings

Non-fatal problems with the activity that was just WRITTEN. Present only on the response to POST /v1/feeds/{group}/{id}/activities; a feed read never carries it — the read path stays exactly three statements.

actor_user_unresolved: the write succeeded, but actor names a user:<id> with no users row, so actor_user is null and every card renders with no name and no avatar until that user is upserted. Without this field a correct write and a broken one are byte-identical. A non-user: actor (system:jobs) never enriches by design and is NOT warned about.

Array<string>
Allowed values: actor_user_unresolved
Example
{
"actor": "user:alice",
"verb": "post",
"object": "workout:123",
"origin_feed": "user:alice",
"reaction_counts": {
"like": 3
},
"own_reactions": [
"like"
],
"refs": [
"session:1234"
],
"warnings": [
"actor_user_unresolved"
]
}

Invalid, expired, revoked, or absent token.

Media typeapplication/json
object
error
required
object
code
required
string
Allowed values: VALIDATION_FAILED UNAUTHENTICATED FORBIDDEN NOT_FOUND CONFLICT RATE_LIMITED INTERNAL CONTENT_REJECTED
message
required
string
requestId
required
string
fields

Present only for VALIDATION_FAILED.

Array<object>
object
path
string
message
string
Example
{
"error": {
"code": "VALIDATION_FAILED"
}
}

Authenticated but not permitted.

Media typeapplication/json
object
error
required
object
code
required
string
Allowed values: VALIDATION_FAILED UNAUTHENTICATED FORBIDDEN NOT_FOUND CONFLICT RATE_LIMITED INTERNAL CONTENT_REJECTED
message
required
string
requestId
required
string
fields

Present only for VALIDATION_FAILED.

Array<object>
object
path
string
message
string
Example
{
"error": {
"code": "VALIDATION_FAILED"
}
}

The (foreign_id, time) identity belongs to a soft-deleted activity. The identity is burned — pick a new one (spec §6).

Media typeapplication/json
object
error
required
object
code
required
string
Allowed values: VALIDATION_FAILED UNAUTHENTICATED FORBIDDEN NOT_FOUND CONFLICT RATE_LIMITED INTERNAL CONTENT_REJECTED
message
required
string
requestId
required
string
fields

Present only for VALIDATION_FAILED.

Array<object>
object
path
string
message
string
Example
{
"error": {
"code": "VALIDATION_FAILED"
}
}

Rate limit exceeded.

Media typeapplication/json
object
error
required
object
code
required
string
Allowed values: VALIDATION_FAILED UNAUTHENTICATED FORBIDDEN NOT_FOUND CONFLICT RATE_LIMITED INTERNAL CONTENT_REJECTED
message
required
string
requestId
required
string
fields

Present only for VALIDATION_FAILED.

Array<object>
object
path
string
message
string
Example
{
"error": {
"code": "VALIDATION_FAILED"
}
}
Retry-After
integer