Outcome Operations
How to use the operation field on outcomesDetailed to represent creates, deletes, and updates within an interaction.
Overview
Each item in outcomesDetailed may include an operation field that indicates whether the outcomeDetail is being created, deleted, or updated. It defaults to "create" when omitted. The value object holding the outcome detail's payload is required.
Valid values are create, delete, and update. Which of these an outcome detail accepts depends on its type:
| Outcome detail type | Accepted operations |
|---|---|
activist_code | create, delete |
survey_response | create, delete |
communication_consent | create, delete |
event_signup | create, update |
Operations for Individual OutcomeDetails
An interaction represents something that happened, e.g. a conversation, an SMS response, etc. The operation field describes what kind of data change an outcome represents.
For example, a voter removing a text message opt-out is a new interaction (something happened), but its effect will change the prior opt-in/opt-out status to unknown. That interaction would use "operation": "delete" on the relevant outcome detail.
Subsequent interactions match by Person
Interactions calls that add an outcomeDetail or delete an outcomeDetail from a previous interaction do so by creating a new interaction with a new interactionId for the same set of Person identifiers. They do not overwrite or alter a previous interaction by interactionId.
Downstream destinations are responsible for deciding how they want to handle interactions sent for the same person with new or altered information.
Idempotency via Interaction IDs
Sending interactions with the same interaction ID is intended to allow requests to be idempotent, not to update an existing interaction. Sending the same interaction ID with different contents is unsupported behavior; destinations will receive the interaction but will either reject it or handle it unpredictably, so you should avoid re-sending interactions with the same ID but different bodies, except in the exception defined below.
Exception for VAN /canvassResponses destination
/canvassResponses destinationThe only exception is that Interactions can be re-sent with different values when targeting VAN as a destination when the initial request fails due to a validation failure and you must make updates.
Examples
Creating an outcome (default behavior)
A volunteer speaks with a voter and records a new activist code. This is the default behavior: "operation": "create" can be included explicitly or omitted.
{
"interactions": [
{
"person": [{ "id": "1234", "type": "CRM" }],
"stateCode": "MA",
"method": "phone_call",
"outcome": "successful_contact",
"attemptDateTime": "2026-03-10T14:21:34.891Z",
"committee": [{ "type": "MyCRM", "id": "poppy-for-governor" }],
"vendorSource": "My CRM",
"outcomesDetailed": [
{
"operation": "create",
"type": "activist_code",
"value": {
"activistCodeId": "42",
"text": "Event Volunteer"
}
}
]
}
]
}Deleting an outcome
E.g. A voter undoes their opt-out from an SMS list, changing their previous status to unknown.
{
"interactions": [
{
"person": [{ "id": "1234", "type": "CRM" }],
"stateCode": "MA",
"method": "text",
"outcome": "successful_contact",
"attemptDateTime": "2026-03-10T14:21:34.891Z",
"committee": [{ "type": "MyCRM", "id": "poppy-for-governor" }],
"vendorSource": "My CRM",
"outcomesDetailed": [
{
"operation": "delete",
"type": "communication_consent",
"value": {
"consentStatus": "opted_out"
}
}
]
}
]
}Mixing operations in a single interaction
A single conversation can produce multiple outcome changes. Here, a volunteer learns that a voter wants to rescind their communications opt-out, and adds a new note about their interaction.
contact_note is not one of the four typed outcome details listed above. Any unrecognized type is accepted and passed through as a loosely-typed detail, but it is not validated, so nothing checks the shape of its value.
{
"interactions": [
{
"person": [{ "id": "1234", "type": "CRM" }],
"stateCode": "MA",
"method": "phone_call",
"outcome": "successful_contact",
"attemptDateTime": "2026-03-10T14:21:34.891Z",
"committee": [{ "type": "MyCRM", "id": "poppy-for-governor" }],
"vendorSource": "My CRM",
"outcomesDetailed": [
{
"operation": "delete",
"type": "communication_consent",
"value": {
"consentStatus": "opted_out"
}
},
{
"operation": "create",
"type": "contact_note",
"value": {
"content": "my new note contents"
}
}
]
}
]
}Data edits from a CRM
A CRM user corrects a voter's record through the UI. They delete a survey response for a given response ID and send a new one with a new value.
There is no dedicated contact method or outcome for a CRM-side data edit. These examples useweb_interactionandother, the closest existing enum members. Values outside the documented enums are rejected.
Note that questionText and responseText are required on every survey response, including a delete.
{
"interactions": [
{
"person": [{ "id": "1234", "type": "MY_CRM" }],
"stateCode": "MA",
"method": "web_interaction",
"outcome": "other",
"attemptDateTime": "2026-03-10T14:21:34.891Z",
"committee": [{ "type": "MyCRM", "id": "poppy-for-governor" }],
"vendorSource": "My CRM",
"outcomesDetailed": [
{
"operation": "delete",
"type": "survey_response",
"value": {
"questionId": "100",
"questionText": "Preferred contact method",
"responseId": "305",
"responseText": "Phone"
}
}
]
}
]
}{
"interactions": [
{
"person": [{ "id": "1234", "type": "MY_CRM" }],
"stateCode": "MA",
"method": "web_interaction",
"outcome": "other",
"attemptDateTime": "2026-03-10T14:21:34.891Z",
"committee": [{ "type": "MyCRM", "id": "poppy-for-governor" }],
"vendorSource": "My CRM",
"outcomesDetailed": [
{
"operation": "create",
"type": "survey_response",
"value": {
"questionId": "100",
"questionText": "Preferred contact method",
"responseId": "305",
"responseText": "Email"
}
}
]
}
]
}Updated 2 months ago

