Submitting a MassID
End-to-end guide for submitting a MassID — create document, add events, and close.
Use this sequence as the base implementation pattern for submitting a complete MassID lifecycle through the Carrot API.
Prerequisites
Before you begin, ensure you have:
- A registered Network Integrator account with valid API credentials
- Participant and address data ready — these are created inline on your first submission (no separate creation step needed)
- Familiarity with core concepts — especially the immutable event-sourced model
Step 1: Create the document
Create the root record with classification and baseline visibility fields. Participant and address data can be sent inline as objects on the first request. On subsequent requests, you can reuse the IDs returned by the platform.
POST /v1/documents
{
"category": "MassID",
"type": "YOUR_WASTE_TYPE",
"measurementUnit": "kg",
"externalCreatedAt": "2026-03-01T10:00:00.000Z",
"isPublic": true,
"isPubliclySearchable": true,
"participant": {
"countryCode": "BR",
"name": "Example Company",
"taxId": "11111111111111",
"taxIdType": "CNPJ",
"type": "COMPANY"
},
"address": {
"name": "Main Facility",
"street": "Rua das Colinas",
"number": "500",
"neighborhood": "Centro",
"city": "São Paulo",
"countryState": "São Paulo",
"countryCode": "BR",
"zipCode": "08575720",
"latitude": -23.5489,
"longitude": -46.6388
},
"externalId": "your-internal-tracking-id",
"deduplicationId": "unique-id-generated-before-first-attempt"
}| Field | Required | Description |
|---|---|---|
category | Yes | Always MassID for mass tracking documents |
type | Yes | Waste type — defined per methodology (see note below) |
measurementUnit | Yes | kg for recycling, kg CO₂e for carbon |
externalCreatedAt | Yes | ISO 8601 timestamp of the real-world document creation |
isPublic | Yes | Whether the document is publicly visible |
isPubliclySearchable | Yes | Whether the document appears in public search |
participant | No* | Inline participant object (see required fields below) |
participantId | No* | ID of an existing participant — use for subsequent requests |
address | No** | Inline address object (see required fields below) |
addressId | No** | ID of an existing address — use for subsequent requests |
externalId | No | Your internal ID for reconciliation — useful for mapping back to your system |
deduplicationId | No | Idempotency key — see tip below |
* Send either participant (inline object) or participantId (ID), not both.
** Send either address (inline object) or addressId (ID), not both.
Inline creation vs. ID reuse
On your first request, send full participant and address objects. The platform creates
them and returns their IDs in the response. On subsequent requests, reuse those IDs via
participantId and addressId instead of resending the full objects.
Methodology-specific values
The type field (waste type) and measurementUnit are defined by your target methodology. See
the methodology integration guides for the
specific values required.
Inline participant required fields:
| Field | Type | Description |
|---|---|---|
countryCode | string | Two-letter country code (ISO 3166-1 alpha-2) |
name | string | Full name or company name |
taxId | string | Tax ID number (digits only, no formatting) |
taxIdType | string | Tax ID type — e.g. CPF, CNPJ |
type | string | PERSON or COMPANY |
Reference: Documents API.
Step 2: Append timeline events
Append events in chronological order to represent operational steps. Each event is immutable once created.
ACTOR events
ACTOR events register participant roles on the document timeline. Each requires a label identifying the role, plus a participant and address:
POST /v1/documents/{documentId}/events
{
"name": "ACTOR",
"label": "YOUR_ROLE_LABEL",
"externalCreatedAt": "2026-03-01T10:05:00.000Z",
"isPublic": true,
"participant": {
"countryCode": "BR",
"name": "Participant Name",
"taxId": "22222222222",
"taxIdType": "CPF",
"type": "PERSON"
},
"address": {
"name": "Collection Site",
"street": "Rua das Colinas",
"number": "500",
"neighborhood": "Centro",
"city": "São Paulo",
"countryState": "São Paulo",
"countryCode": "BR",
"zipCode": "08575720",
"latitude": -23.5489,
"longitude": -46.6388
}
}The label value (e.g. "Waste Generator", "Hauler", "Processor") is defined by each methodology. See your methodology guide for the required roles and their labels.
After the first inline creation, you can use participantId and addressId for subsequent events referencing the same participant or address.
CUSTOM events
CUSTOM events represent methodology-specific operational steps. The event name, required metadata attributes, and sequence are all defined by the methodology:
POST /v1/documents/{documentId}/events
{
"name": "YOUR_EVENT_NAME",
"externalCreatedAt": "2026-03-01T11:00:00.000Z",
"isPublic": true,
"participantId": "participant-id-from-previous-response",
"addressId": "address-id-from-previous-response",
"metadata": {
"attributes": [
{ "name": "YOUR_ATTRIBUTE_NAME", "value": "attribute-value" }
]
},
"value": 150.5
}The value field on events contributes to the document's currentValue. For example, a weighing event with value: 150.5 sets the tracked weight.
Methodology guides
Each methodology defines the specific event sequence, event names, and required metadata attributes. See the methodology integration guides for the values required by each methodology.
Inline address required fields:
| Field | Type | Description |
|---|---|---|
city | string | City name |
countryCode | string | Two-letter country code (ISO 3166-1 alpha-2) |
countryState | string | State or province |
latitude | number | Latitude coordinate |
longitude | number | Longitude coordinate |
name | string | Descriptive name for the address |
neighborhood | string | Neighborhood or district |
number | string | Street number |
street | string | Street name |
zipCode | string | Postal code (digits only, no formatting) |
Document status lifecycle
Documents follow a strict status lifecycle:
OPEN— Default status after creation. Events can be appended freely.CLOSEevent — Transitions the document toCLOSED. After closing, onlyRELATEDevents are accepted.CANCELevent — Transitions the document toCANCELLED. No further events are accepted.
Send a CLOSE event when the supply chain lifecycle is complete:
POST /v1/documents/{documentId}/events
{
"name": "CLOSE",
"externalCreatedAt": "2026-03-02T16:00:00.000Z",
"isPublic": true,
"participantId": "integrator-participant-id"
}See Event Specification for the full list of event categories.
Reference: Events API.
For high-volume integrations, consider the batch events endpoint to submit multiple events per request.
Step 3: Attach evidence files (optional)
Some methodology rules require evidence attachments (e.g. scale tickets, transport manifests). The pattern is:
- Request a pre-signed upload URL via the Attachments API
- Upload the file directly to the pre-signed URL
- Reference the attachment in the relevant event's
attachmentsarray
Attachments are linked to specific events, not to the document as a whole. This ensures each piece of evidence is tied to the operational step it documents.
Reference: Attachments API.
Step 4: Retrieve and validate final state
Fetch the document and verify before considering the submission complete:
- Event count and ordering — all expected events are present in chronological order
- Status is
CLOSED— the document has been properly closed currentValue> 0 — the document has a positive tracked value- At least one
ACTORevent — the required participant roles are registered - Participant and address links — all references resolve correctly
- Metadata completeness — required attributes are present on each event per the methodology
Reference: GET document by ID.
Operational tips
deduplicationId
Always send deduplicationId on retryable write calls (document creation and event creation).
Generate a unique ID before the first attempt, store it, and reuse the same ID on every
retry. The ID is scoped per integrator — two different integrators can use the same ID without
conflict. This guarantees at-most-once semantics: if the server received your first request but
the response was lost, the retry will return the original result instead of creating a duplicate.
- Use
externalIdon documents and events for reconciliation with your internal systems. - Treat
4xxas data/integration issues and5xxas transient failures — see Error Handling. - Keep your source timestamp strategy deterministic — see Data Formats.