API Execution Payloads
This guide documents how external systems interact with Guardian policy blocks through the REST API. It is the primary reference for integrators building MRV data pipelines, verification systems, or any application that submits data into a Guardian policy.
Overview
A Guardian policy is a directed graph of blocks. External systems interact with blocks through three patterns:
Read block state
GET
/api/v1/policies/{policyId}/blocks/{blockId}
Get current form schema, document list, or block UI state
Submit data
POST
/api/v1/policies/{policyId}/blocks/{blockId}
Submit a form, trigger a button, select a role
Push external data
POST
/api/v1/external/{policyId}/{blockTag}
Push MRV/oracle data without a Guardian user session
Authentication
All block API calls require a JWT Bearer token from POST /api/v1/accounts/login.
Authorization: Bearer <jwt_token>The calling user must have been assigned the appropriate role within the policy.
Standard Block Response Envelope
When calling GET /policies/{policyId}/blocks/{blockId}, Guardian returns a block-specific response. All responses share these common fields:
id
string
Block UUID
blockType
string
Block type identifier from BlockType enum
policyId
string
Owning policy ID
readonly
boolean
Whether the calling user can submit data to this block
uiMetaData
object
Block-specific display configuration (title, description, type)
Block Data Submission Response
When calling POST /policies/{policyId}/blocks/{blockId} or POST /policies/{policyId}/tag/{tagName}/blocks, Guardian acknowledges the submission synchronously and returns a response that includes a trackingId for correlating the request with the async completion event.
trackingId
string
UUID that uniquely identifies this block execution. Matches the trackingId in the external-events.block_complete event, allowing external systems to correlate requests with async outcomes without polling.
response
object
Present when history=true. The direct output of blockSetData.
result
object
Present when history=true. The final result from the last downstream step.
steps
array
Present when history=true. Ordered list of intermediate step results across the async execution chain. Empty array when history is not requested.
Example response (default):
Example response with history=true:
The submission response is returned as soon as the block accepts the data. The full async chain (IPFS uploads, HCS message submissions, downstream block execution) continues in the background and is reported via the
external-events.block_completeevent.
Block-Specific Payloads
requestVcDocumentBlock
requestVcDocumentBlockPresents a data entry form based on a schema. The user fills the form and submits a VC document.
GET response — block state:
POST request — submit document:
document
object
Yes
VC document to submit
document.credentialSubject
array
Yes
Array with one object containing schema-defined fields
ref
string
No
Parent document ID for relationship linking
uploadVcDocumentBlock
uploadVcDocumentBlockAccepts file uploads or pre-built VC documents.
POST request:
interfaceDocumentsSourceBlock
interfaceDocumentsSourceBlockDisplays a list of documents to the user. Read-only; no POST required.
GET response:
buttonBlock
buttonBlockDisplays action buttons that trigger workflow transitions (e.g., Approve/Reject).
GET response:
POST request — trigger a button:
document
object
Yes
The document to act on (must include id)
tag
string
Yes
Button tag to trigger — must match one of uiMetaData.buttons[].tag
policyRolesBlock
policyRolesBlockAssigns a role to the current user within the policy.
GET response:
POST request — select role:
role
string
Yes
Role name — must be one of the values in the GET response roles array
mintDocumentBlock
mintDocumentBlockMints environmental asset tokens after document approval. This is a server-side block (post: false, get: false) — it is triggered automatically by the policy engine when an upstream block fires a RunEvent. There is no direct GET or POST available from the API.
The block calculates a token amount by evaluating the configured rule expression against the incoming VC documents, creates a mint VC and VP, publishes both to HCS, and calls the Hedera token service to mint the tokens to the target account.
To observe mint outcomes, query the interfaceDocumentsSourceBlock that follows the mint block in the policy flow — documents there will carry a type of "MINT" once minting completes.
retirementDocumentBlock
retirementDocumentBlockRetires (wipes) tokens from a holder account. This is a server-side block (post: false, get: false) — it is triggered automatically by the policy engine when an upstream block fires a RunEvent. There is no direct GET or POST available from the API.
The block evaluates the configured rule expression (fungible tokens) or serial number expression (non-fungible tokens) against the incoming VC documents, creates a wipe VC and VP, publishes both to HCS, and calls the Hedera token wipe service.
createTokenBlock
createTokenBlockPresents a token configuration form that allows a user to define and create a new Hedera token within the policy's token template. The block can also be set to autorun, in which case it creates the token automatically without user interaction.
GET response — token template:
Fields already locked by the policy template will be returned in data but cannot be overridden in the POST — submit only the fields the policy leaves editable.
POST request — submit token configuration:
tokenName
string
Human-readable token name
tokenSymbol
string
Short token symbol (e.g. "iREC")
tokenType
string
"fungible" or "non-fungible"
decimals
string
Decimal precision for fungible tokens (e.g. "2")
initialSupply
string
Initial supply for fungible tokens (e.g. "0")
enableAdmin
boolean
Enables admin key on the token
changeSupply
boolean
Enables supply key (required for minting)
enableFreeze
boolean
Enables freeze key
enableKYC
boolean
Enables KYC key
enableWipe
boolean
Enables wipe key (required for retirement)
wipeContractId
string | null
Optional Hedera contract ID to use as wipe key
On success the block publishes the new token to HCS, stores the resulting tokenId in the policy document's tokens map, and fires a RunEvent to the next block.
tokenConfirmationBlock
tokenConfirmationBlockPrompts the current user to associate (or dissociate) their Hedera account with a specific token, or to skip the step. This is required before a user can receive minted tokens.
GET response:
action
string
"associate" or "dissociate" — the operation the user is being asked to confirm
accountId
string
The user's Hedera account ID that will be associated
tokenName
string
Display name of the token
tokenId
string
Hedera token ID to associate
POST request — confirm association:
POST request — skip:
action
string
Yes
"confirm" to proceed with the association/dissociation, "skip" to bypass
hederaAccountKey
string
Only when action is "confirm"
The user's Hedera ED25519 private key (hex or DER-encoded) used to sign the association transaction
Security note:
hederaAccountKeyis transmitted over HTTPS and used in-process to sign the Hedera association transaction. It is not stored by Guardian.
externalDataBlock
externalDataBlockReceives data pushed from external systems. This is the block to target with POST /external/{policyId}/{blockTag}.
GET response:
External push via POST /api/v1/external/{policyId}/{blockTag}:
owner
string
Yes
DID of the document submitter
policyTag
string
Yes
Policy tag string (from policy configuration)
document
object
Yes
Full or partial VC document
document.credentialSubject
array
Yes
Array containing one credential subject with schema fields
reportBlock
reportBlockGenerates a trust chain / audit trail view. Read-only.
GET response:
switchBlock
switchBlockRoutes documents to different workflow paths based on conditions. Evaluated automatically by the policy engine — no external interaction required.
aggregateDocumentBlock
aggregateDocumentBlockCollects multiple documents until a threshold is met, then batches them. Evaluated automatically.
calculateContainerBlock / mathBlock
calculateContainerBlock / mathBlockPerforms arithmetic on document fields. Evaluated automatically.
sendToGuardianBlock
sendToGuardianBlockSends a document to the Hedera blockchain (IPFS + HCS). Evaluated automatically after form submission or approval.
External Data Submission API Reference
POST /api/v1/external/{policyId}/{blockTag}
The primary integration endpoint for external MRV systems, IoT sensors, and oracles.
Authentication: Not required for externalDataBlock configured as public. JWT required otherwise.
Path Parameters:
policyId
string
Yes
Policy MongoDB ID or published policy message ID
blockTag
string
Yes
Unique tag of the target externalDataBlock
Full Request Body Schema:
The proof field is optional — Guardian will sign the document if not provided.
Response 200 OK:
Error Codes:
400
Missing required fields
404
Policy or block tag not found
422
Document validation failed against policy schema
500
Internal server error
Tag-Based Block Access
Blocks can also be accessed by tag name instead of UUID:
This is useful when block UUIDs change between policy versions but tags remain stable.
Complete Integration Workflow
Step 1 — Authenticate
Step 2 — Find Published Policy
Locate the policy by name or policyTag in the response. Note its id.
Step 3 — Navigate to Roles Block
Find the policyRolesBlock in the block tree. Note its id.
Step 4 — Select Role
Step 5 — Get Submission Form Schema
Extract the schema.properties to determine which fields to populate.
Step 6 — Submit Document
The response includes a trackingId to correlate this submission with its async completion event:
Step 7 — Track Async Completion
Guardian processes block submissions asynchronously. IPFS uploads, HCS message submissions, and downstream blocks all run after the POST returns. There are two ways to observe completion:
Option A — Subscribe to external-events.block_complete (recommended)
Configure a webhook or SSE listener for the external-events.block_complete event. When the full async chain settles, Guardian emits:
Match the event's trackingId to the value returned in Step 6 to confirm your submission completed. When status is "failure", the error and errorDetails fields contain diagnostics.
trackingId
string
Matches the value returned by the POST response in Step 6
blockType
string
Block type that processed the submission
blockTag
string
Block tag identifier
blockId
string
Block UUID
policyId
string
Policy ID
userId
string
DID of the submitting user
status
string
"success" or "failure"
outputData
object
Optional. Direct output from blockSetData when available
error
string
Optional. Human-readable description of the first error (when status is "failure")
errorDetails
array
Optional. All errors collected across the async chain — each entry has message and optional stack
timestamp
number
Unix millisecond timestamp when completion was determined
Option B — Poll document status
Poll until data[0].option.status changes to APPROVED or REJECTED. Use this when you cannot configure an event listener.
Last updated
Was this helpful?