How to Manage a Case Roster
Use this guide to run the full participant lifecycle on a case: invite an actor, seat it when it accepts, record its status, remove it from active participation, and reinstate it. Every step routes through the CASE_MANAGER, which is the authoritative recipient of case-management handshake messages once a case exists. You finish with a case whose active participants are the ones actually working it.
Prerequisites
- A running Vultron instance you can drive. The demo containers are the quickest route — see Tutorial: Run the Receive-Report Demo for the two steps that get you a container shell.
- An actor identity on that instance, holding the role each step names.
- Working knowledge of the ActivityStreams verb, object, and target shape, summarized in Vultron and ActivityPub.
-
Working knowledge of the case model: the objects a case is made of, in The Case Model, and who is allowed to change them, in The CASE_MANAGER and the Case Ledger. Where a guide's messages are case-scoped, they route through the CASE_MANAGER and their results appear on the case ledger.
-
An existing case.
- The Case Owner role for invitations, removals and reinstatements. Any participant can record its own status.
- The CASE_MANAGER's actor Uniform Resource Identifier (URI), which is where handshake replies go.
The lifecycle
The flowchart below shows the roster path from invitation to removal and back.
The decision diamonds are the loop a long-running case sits in: status updates accumulate, a participant leaves active participation only when Remove? is answered yes, and it returns only when Reinstate? is answered yes.
---
title: Case Roster Over the Life of a Case
---
flowchart TB
subgraph as:Invite
RmInviteToCase["Invite Actor to Case<br/>Invite(Actor)"]
end
subgraph as:Accept
RmAcceptInviteToCase["Accept Invite to Case<br/>Accept(Invite(Actor))"]
end
subgraph as:Reject
RmRejectInviteToCase["Reject Invite to Case<br/>Reject(Invite(Actor))"]
end
subgraph as:Add
AddStatusToParticipant["Vendor Awareness (CV) / Fix Readiness (CF) / Fix Deployed (CD)<br/>Add(ParticipantStatus)"]
AddParticipantToCase["Reinstate Case Participant<br/>Add(CaseParticipant)"]
end
subgraph as:Remove
RemoveParticipantFromCase["Remove Case Participant from Case<br/>Remove(CaseParticipant)"]
end
start([Start])
start --> RmInviteToCase
RmInviteToCase --> a{Accept?}
a -->|y| RmAcceptInviteToCase
a -->|n| RmRejectInviteToCase
RmAcceptInviteToCase --> s{Status?}
s -->|y| AddStatusToParticipant
s -->|n| r{Remove?}
AddStatusToParticipant --> r
r -->|y| RemoveParticipantFromCase
r -->|n| s
RemoveParticipantFromCase --> b{Reinstate?}
b -->|y| AddParticipantToCase
AddParticipantToCase --> s
Admit an actor
- Trigger the invitation.
The CASE_MANAGER sends
Invite(Actor)with itself as the ActivityStreamsactorand your Case Owner identity inattributedTo(PCR-08-007, PCR-08-008). - Wait for the invitee's reply, addressed to the CASE_MANAGER.
- If the reply is
Accept(Invite(Actor)), the CASE_MANAGER makes the actor an active participant — see How to Seat a Participant on an Existing Case. The CASE_MANAGER ledgers the record's creation when it sends the Invite, and the invitee'sAccept(Invite(Actor))is the ledger entry for its consent andjoinedmark; a replica applies those entries, and nothing else is sent to seat it. - If the reply is
Reject(Invite(Actor)), stop. The actor never becomes active, and nothing further is owed. The CASE_MANAGER keeps its inert participant record at RMCLOSED.
For the full invitation sequence, including the routing rule and its rationale, see How to Invite an Actor to a Case.
Do not address the handshake to the Case Owner
An invitee that replies directly to the Case Owner bypasses the CASE_MANAGER, so the reply is never committed to the ledger and no replica learns of it.
Address Accept(Invite(Actor)) and Reject(Invite(Actor)) to the CASE_MANAGER.
Judge the case after joining
Once a participant is seated, the CASE_MANAGER sends it a second invitation, Invite(Actor) with the case as its target, after the case announcement and the ledger replay.
This full-case Invite carries the CASE_MANAGER's ledger position in the standard ActivityStreams content field, as the JSON of the LedgerPosition model (log_index and entry_hash).
The target stays the plain case URI.
That position is the floor: the participant's reply must reach it.
Send Full-Case Invite
Sends the Full-Case Invite, which asks the Participant to judge the case. It carries the Case Manager's ledger position as the floor the reply must reach.
- When… the Case Manager has replayed the case ledger to a newly joined Participant
- Send:
Invite(Actor)[target=VulnerabilityCase] - Send to: a participant
- Sent by: the case manager
- Reference: Send Full-Case Invite
Example activity
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Invite",
"id": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0/full-case-invitation/1",
"name": "https://vultron.example/case-actors/vendorco-case-actor Invite Coordinator LLC to urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0",
"context": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0",
"content": "{\"logIndex\":4,\"entryHash\":\"b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5\"}",
"to": "https://vultron.example/organizations/coordinator",
"actor": "https://vultron.example/case-actors/vendorco-case-actor",
"target": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0",
"object": {
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Organization",
"id": "https://vultron.example/organizations/coordinator",
"name": "Coordinator LLC",
"published": "2026-10-23T20:17:06+00:00",
"updated": "2026-10-23T20:17:06+00:00",
"inbox": {
"@context": "https://www.w3.org/ns/activitystreams",
"type": "OrderedCollection",
"id": "https://vultron.example/organizations/coordinator/inbox",
"items": []
},
"outbox": {
"@context": "https://www.w3.org/ns/activitystreams",
"type": "OrderedCollection",
"id": "https://vultron.example/organizations/coordinator/outbox",
"items": []
}
}
}
- Wait until your copy of the ledger has caught up to the Invite's position.
The trigger fails closed with
409until it has, so retry once replication catches up. -
Trigger one reply, naming the Invite in
invite_id:-
POST /actors/{actor_id}/trigger/accept-full-case-invitesendsAccept, and the CASE_MANAGER records Report Valid (RECEIVEDtoVALID).Accept Full-Case Invite
Accepts the Full-Case Invite, which records RM Valid. It carries the sender's own ledger position.
- When… a Participant asked by a Full-Case Invite judges the case valid
- Send:
Accept(Invite(Actor)[target=VulnerabilityCase]) - Send to: the case manager
- Sent by: the invitee
- Reference: Accept Full-Case Invite
Example activity
{ "@context": "https://www.w3.org/ns/activitystreams", "type": "Accept", "id": "urn:uuid:425d7b92-d351-4b97-a303-b84f864799e2", "name": "https://vultron.example/organizations/coordinator Accept https://vultron.example/case-actors/vendorco-case-actor Invite Coordinator LLC to urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "inReplyTo": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0/full-case-invitation/1", "content": "{\"logIndex\":4,\"entryHash\":\"b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5\"}", "to": "https://vultron.example/case-actors/vendorco-case-actor", "actor": "https://vultron.example/organizations/coordinator", "object": { "@context": "https://www.w3.org/ns/activitystreams", "type": "Invite", "id": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0/full-case-invitation/1", "name": "https://vultron.example/case-actors/vendorco-case-actor Invite Coordinator LLC to urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "context": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "published": "2026-10-23T20:17:08+00:00", "updated": "2026-10-23T20:17:08+00:00", "content": "{\"logIndex\":4,\"entryHash\":\"b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5\"}", "to": "https://vultron.example/organizations/coordinator", "actor": "https://vultron.example/case-actors/vendorco-case-actor", "target": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "object": { "@context": "https://www.w3.org/ns/activitystreams", "type": "Organization", "id": "https://vultron.example/organizations/coordinator", "name": "Coordinator LLC", "published": "2026-10-23T20:17:06+00:00", "updated": "2026-10-23T20:17:06+00:00", "inbox": { "@context": "https://www.w3.org/ns/activitystreams", "type": "OrderedCollection", "id": "https://vultron.example/organizations/coordinator/inbox", "items": [] }, "outbox": { "@context": "https://www.w3.org/ns/activitystreams", "type": "OrderedCollection", "id": "https://vultron.example/organizations/coordinator/outbox", "items": [] } } } } -
POST /actors/{actor_id}/trigger/tentative-reject-full-case-invitesendsTentativeReject, and the CASE_MANAGER records Report Invalid (RECEIVEDtoINVALID).Tentatively reject Full-Case Invite
Tentatively rejects the Full-Case Invite, which records RM Invalid. It carries the sender's own ledger position.
- When… a Participant asked by a Full-Case Invite judges the case invalid
- Send:
TentativeReject(Invite(Actor)[target=VulnerabilityCase]) - Send to: the case manager
- Sent by: the invitee
- Reference: Tentatively reject Full-Case Invite
Example activity
{ "@context": "https://www.w3.org/ns/activitystreams", "type": "TentativeReject", "id": "urn:uuid:f5b6083e-ac9f-4b6d-94ee-46ed4a46aa59", "name": "https://vultron.example/organizations/coordinator TentativeReject https://vultron.example/case-actors/vendorco-case-actor Invite Coordinator LLC to urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "inReplyTo": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0/full-case-invitation/1", "content": "{\"logIndex\":4,\"entryHash\":\"b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5\"}", "to": "https://vultron.example/case-actors/vendorco-case-actor", "actor": "https://vultron.example/organizations/coordinator", "object": { "@context": "https://www.w3.org/ns/activitystreams", "type": "Invite", "id": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0/full-case-invitation/1", "name": "https://vultron.example/case-actors/vendorco-case-actor Invite Coordinator LLC to urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "context": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "published": "2026-10-23T20:17:08+00:00", "updated": "2026-10-23T20:17:08+00:00", "content": "{\"logIndex\":4,\"entryHash\":\"b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5\"}", "to": "https://vultron.example/organizations/coordinator", "actor": "https://vultron.example/case-actors/vendorco-case-actor", "target": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "object": { "@context": "https://www.w3.org/ns/activitystreams", "type": "Organization", "id": "https://vultron.example/organizations/coordinator", "name": "Coordinator LLC", "published": "2026-10-23T20:17:06+00:00", "updated": "2026-10-23T20:17:06+00:00", "inbox": { "@context": "https://www.w3.org/ns/activitystreams", "type": "OrderedCollection", "id": "https://vultron.example/organizations/coordinator/inbox", "items": [] }, "outbox": { "@context": "https://www.w3.org/ns/activitystreams", "type": "OrderedCollection", "id": "https://vultron.example/organizations/coordinator/outbox", "items": [] } } } } -
POST /actors/{actor_id}/trigger/reject-full-case-invitesendsReject, and the CASE_MANAGER records Report Closed (RECEIVEDtoCLOSED).Reject Full-Case Invite
Rejects the Full-Case Invite, which records RM Closed. It carries the sender's own ledger position.
- When… a Participant asked by a Full-Case Invite closes the case
- Send:
Reject(Invite(Actor)[target=VulnerabilityCase]) - Send to: the case manager
- Sent by: the invitee
- Reference: Reject Full-Case Invite
Example activity
{ "@context": "https://www.w3.org/ns/activitystreams", "type": "Reject", "id": "urn:uuid:2107f529-1f4c-4c5c-8f10-635211955d56", "name": "https://vultron.example/organizations/coordinator Reject https://vultron.example/case-actors/vendorco-case-actor Invite Coordinator LLC to urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "inReplyTo": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0/full-case-invitation/1", "content": "{\"logIndex\":4,\"entryHash\":\"b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5\"}", "to": "https://vultron.example/case-actors/vendorco-case-actor", "actor": "https://vultron.example/organizations/coordinator", "object": { "@context": "https://www.w3.org/ns/activitystreams", "type": "Invite", "id": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0/full-case-invitation/1", "name": "https://vultron.example/case-actors/vendorco-case-actor Invite Coordinator LLC to urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "context": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "published": "2026-10-23T20:17:08+00:00", "updated": "2026-10-23T20:17:08+00:00", "content": "{\"logIndex\":4,\"entryHash\":\"b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5b2c3d4e5\"}", "to": "https://vultron.example/organizations/coordinator", "actor": "https://vultron.example/case-actors/vendorco-case-actor", "target": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "object": { "@context": "https://www.w3.org/ns/activitystreams", "type": "Organization", "id": "https://vultron.example/organizations/coordinator", "name": "Coordinator LLC", "published": "2026-10-23T20:17:06+00:00", "updated": "2026-10-23T20:17:06+00:00", "inbox": { "@context": "https://www.w3.org/ns/activitystreams", "type": "OrderedCollection", "id": "https://vultron.example/organizations/coordinator/inbox", "items": [] }, "outbox": { "@context": "https://www.w3.org/ns/activitystreams", "type": "OrderedCollection", "id": "https://vultron.example/organizations/coordinator/outbox", "items": [] } } } }
-
-
The reply carries your own ledger position in
content. The CASE_MANAGER refuses, and writes nothing for, a reply that is behind the Invite's position or names a ledger entry it does not hold.
A later Join or Ignore moves the participant to ACCEPTED or DEFERRED as it does for any participant.
Record a participant's status
Vendor Awareness (CV), Fix Readiness (CF) and Fix Deployed (CD) are all implemented in ActivityStreams as Add(ParticipantStatus).
Which one you are sending is determined by the field you set, not by a different activity.
See How to Post a Status Update or a Case Note for the field that selects each.
Send Add(ParticipantStatus), targeting the participant record, with the new status inline as its object.
The status carries the participant's rmState and, for a Vendor or Deployer, its vfState and dState.
The protocol names Add(ParticipantStatus) as the one form; a received Create(ParticipantStatus) is not a protocol message (VAM-01-011), and this implementation's inbox refuses it as an unrecognized activity (VAM-01-010).
If the status is known when you seat the participant, carry it inline on the CaseParticipant object instead of sending the Add.
Status is self-declaratory: send your own, and expect each participant to send its own (PRM-06-001, ADR-0121).
Remove a participant
Only the Case Owner removes a participant.
Send Remove(CaseParticipant) to the CASE_MANAGER, with the participant as its object and the case as its target.
If you are both the Case Owner and the CASE_MANAGER, send it to your own inbox.
Remove case participant from case
Asks the Case Manager to remove the participant record named by the object. The removed Participant receives a direct notice.
- When… the Case Owner removes a Participant from active participation
- Send:
Remove(CaseParticipant)[target=VulnerabilityCase] - Send to: the case manager
- Sent by: the case owner
- Reference: Remove case participant from case
Example activity
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Remove",
"id": "urn:uuid:67f06741-9346-4f0f-85af-a59453502025",
"name": "https://vultron.example/organizations/vendorco Remove Coordinator LLC to urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0",
"context": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0",
"summary": "Vendor is removing the coordinator from the case.",
"actor": "https://vultron.example/organizations/vendorco",
"target": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0",
"object": {
"id": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0/participants/coordinator",
"type": "CaseParticipant",
"name": "Coordinator LLC",
"context": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0",
"published": "2026-10-23T20:17:08+00:00",
"updated": "2026-10-23T20:17:08+00:00",
"attributedTo": "https://vultron.example/organizations/coordinator",
"caseRoles": [
"coordinator"
],
"participantStatuses": [
{
"id": "urn:uuid:3950dda2-6765-4a12-93d7-3be444f49df7",
"type": "ParticipantStatus",
"name": "START",
"context": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0",
"published": "2026-10-23T20:17:08+00:00",
"updated": "2026-10-23T20:17:08+00:00",
"attributedTo": "https://vultron.example/organizations/coordinator",
"rmState": "START",
"caseEngagement": true,
"cvdRole": [
"COORDINATOR"
],
"@context": "https://certcc.github.io/Vultron/ns/context.jsonld"
}
],
"embargoConsents": [],
"joined": true,
"@context": "https://certcc.github.io/Vultron/ns/context.jsonld"
}
}
Name the case in target, not origin
origin reads like the right field for a removal, and it is not one the receiver looks at: dispatch discriminates on target, so a Remove that names the case only in origin matches no pattern and the participant is never removed (#3438).
Removal withdraws the participant's entitlement to case content. It does not take the participant off the roster: its record, its status history and its embargo consent stay, and the record carries a removal fact. The CASE_MANAGER refuses a removal of the CASE_MANAGER or of the Case Owner, and a removal from anyone other than the Case Owner. A second removal of the same participant changes nothing.
The CASE_MANAGER records your Remove as one ledger entry and sends that entry to every active participant, the removed one included.
It then sends the removed participant a direct Remove(CaseParticipant) naming it, with attributedTo set to you.
The removed participant receives no later ledger entries, and no Invite of any kind.
The CASE_MANAGER also refuses a recommendation that names the removed participant, and your acceptance of an earlier one; reinstate the participant instead.
A removed signatory stays bound by the embargo it accepted.
When that embargo is terminated, or replaced by a revision that ends no later, the CASE_MANAGER sends the removed participant the change directly, outside the ledger (see Embargo Termination (ET)).
See Participant Removal.
Removal is not a closure — a participant that has finished its own work closes with Leave(VulnerabilityCase) instead.
See How to Advance a Case Through Report Management.
Reinstate a participant
Only the Case Owner reinstates a removed participant.
Send Add(CaseParticipant) to the CASE_MANAGER, with the removed participant as its object and the case as its target.
If you are both the Case Owner and the CASE_MANAGER, send it to your own inbox.
Add case participant to case
Asks the Case Manager to reinstate the participant record named by the object. The Participant becomes active again and receives the ledger entries it missed.
- When… the Case Owner reinstates a removed Participant
- Send:
Add(CaseParticipant)[target=VulnerabilityCase] - Send to: the case manager
- Sent by: the case owner
- Reference: Add case participant to case
Example activity
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Add",
"id": "urn:uuid:89e228f1-45aa-42d3-9a2c-9c895e68d78f",
"name": "https://vultron.example/organizations/vendorco Add Coordinator LLC to urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0",
"context": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0",
"content": "We're reinstating the coordinator in this case.",
"actor": "https://vultron.example/organizations/vendorco",
"target": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0",
"object": {
"id": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0/participants/coordinator",
"type": "CaseParticipant",
"name": "Coordinator LLC",
"context": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0",
"published": "2026-10-23T20:17:08+00:00",
"updated": "2026-10-23T20:17:08+00:00",
"attributedTo": "https://vultron.example/organizations/coordinator",
"caseRoles": [
"coordinator"
],
"participantStatuses": [
{
"id": "urn:uuid:7202e74f-5d7b-494b-82fd-97d4996a36f3",
"type": "ParticipantStatus",
"name": "START",
"context": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0",
"published": "2026-10-23T20:17:08+00:00",
"updated": "2026-10-23T20:17:08+00:00",
"attributedTo": "https://vultron.example/organizations/coordinator",
"rmState": "START",
"caseEngagement": true,
"cvdRole": [
"COORDINATOR"
],
"@context": "https://certcc.github.io/Vultron/ns/context.jsonld"
}
],
"embargoConsents": [],
"joined": true,
"@context": "https://certcc.github.io/Vultron/ns/context.jsonld"
}
}
Reinstatement clears the removal fact.
The participant does not accept again: it never withdrew, so it keeps its roles, its status history and its embargo consent.
The CASE_MANAGER refuses an Add from anyone other than the Case Owner, and an Add that names a participant that is not removed or that never joined.
Add(CaseParticipant) does not seat a new member; an actor joins only by accepting its stub Invite.
The CASE_MANAGER records your Add as one ledger entry.
When the participant is active again, the CASE_MANAGER sends it every ledger entry committed after its removal entry, in log order, then a direct Add(CaseParticipant) naming it, with attributedTo set to you.
A participant that has not accepted the active embargo stays inert: the CASE_MANAGER sends it that embargo's Invite instead, and its catch-up waits until it accepts.
Verify
| What you sent | What to confirm |
|---|---|
Invite(Actor) |
The invitee holds an Invite whose actor is the CASE_MANAGER. |
Accept(Invite(Actor)) |
The roster holds the participant with its roles. |
Add(ParticipantStatus) |
The participant record carries the new status. |
Remove(CaseParticipant) |
The roster still lists the participant, and its record names your Remove as its removalActivity. |
Add(CaseParticipant) |
The participant's record has no removalActivity, and the participant holds the ledger entries it missed. |
Accept, TentativeReject or Reject of the full-case Invite |
The CASE_MANAGER's record of the participant shows RM VALID, INVALID or CLOSED. |
See it end to end
Try it: vultron-demo manage-participants
vultron-demo manage-participants
Or with Docker Compose:
DEMO=manage-participants docker compose -f docker/docker-compose.yml run --rm demo
The scenario runs invite, accept, status update, removal, and reinstatement, then the rejection path.
Further reading
- Case Management Messages — the wire format and a rendered example for each activity above
- Case State (CS) Messages — the status fields
Add(ParticipantStatus)carries - Activity Vocabulary Design — why
as:Inviteasks whereas:Addasserts - Trigger API Reference — request schema and endpoint details for
suggest-actor-to-case,invite-actor-to-case,accept-case-invite, andreject-case-invite