cURL
curl --request POST \
--url https://test-api.shodai.network/v0/agreements/validate-template \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"metadata": {
"templateId": "did:template:service-retainer-v0-1",
"name": "Service Retainer"
},
"variables": {
"serviceProviderRepresentative": {
"type": "address",
"subtype": "participant",
"validation": {
"required": true
}
},
"clientRepresentative": {
"type": "address",
"subtype": "participant",
"validation": {
"required": true
}
},
"retainerTitle": {
"type": "string",
"validation": {
"required": true
}
}
},
"content": {
"type": "md",
"data": "# ${variables.retainerTitle}\n\nService agreement between provider and client."
},
"execution": {
"initialize": {
"initialState": "AWAITING_PAYMENT",
"data": {}
},
"states": {
"AWAITING_PAYMENT": {
"description": "Waiting for initial payment proof."
},
"WORK_IN_PROGRESS": {
"description": "Provider is performing the service."
}
},
"inputs": {
"submitInitialPaymentProof": {
"issuer": {
"type": "participant",
"variable": "clientRepresentative"
},
"schema": {
"paymentReference": {
"type": "string",
"validation": {
"required": true
}
}
}
}
},
"transitions": [
{
"from": "AWAITING_PAYMENT",
"to": "WORK_IN_PROGRESS",
"conditions": [
{
"input": "submitInitialPaymentProof"
}
]
}
]
}
}
'const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
metadata: {templateId: 'did:template:service-retainer-v0-1', name: 'Service Retainer'},
variables: {
serviceProviderRepresentative: {type: 'address', subtype: 'participant', validation: {required: true}},
clientRepresentative: {type: 'address', subtype: 'participant', validation: {required: true}},
retainerTitle: {type: 'string', validation: {required: true}}
},
content: {
type: 'md',
data: '# ${variables.retainerTitle}\n\nService agreement between provider and client.'
},
execution: {
initialize: {initialState: 'AWAITING_PAYMENT', data: {}},
states: {
AWAITING_PAYMENT: {description: 'Waiting for initial payment proof.'},
WORK_IN_PROGRESS: {description: 'Provider is performing the service.'}
},
inputs: {
submitInitialPaymentProof: {
issuer: {type: 'participant', variable: 'clientRepresentative'},
schema: {paymentReference: {type: 'string', validation: {required: true}}}
}
},
transitions: [
{
from: 'AWAITING_PAYMENT',
to: 'WORK_IN_PROGRESS',
conditions: [{input: 'submitInitialPaymentProof'}]
}
]
}
})
};
fetch('https://test-api.shodai.network/v0/agreements/validate-template', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"data": {
"templateId": "did:template:service-retainer-v0-1",
"participantVariableKeys": [
"serviceProviderRepresentative",
"clientRepresentative"
],
"inputIds": [
"submitInitialPaymentProof"
],
"stateIds": [
"AWAITING_PAYMENT",
"WORK_IN_PROGRESS"
],
"warnings": []
},
"meta": {
"apiVersion": "v0",
"requestId": "req_123"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API key",
"requestId": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API key",
"requestId": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API key",
"requestId": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API key",
"requestId": "<string>",
"details": "<unknown>"
}
}Authoring
Validate agreement structure
Checks only the authored agreement JSON and returns participant variable keys, input IDs, state IDs, and warnings. This does not validate deployment values, participant wallet addresses, signer, or permit data.
POST
/
v0
/
agreements
/
validate-template
cURL
curl --request POST \
--url https://test-api.shodai.network/v0/agreements/validate-template \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"metadata": {
"templateId": "did:template:service-retainer-v0-1",
"name": "Service Retainer"
},
"variables": {
"serviceProviderRepresentative": {
"type": "address",
"subtype": "participant",
"validation": {
"required": true
}
},
"clientRepresentative": {
"type": "address",
"subtype": "participant",
"validation": {
"required": true
}
},
"retainerTitle": {
"type": "string",
"validation": {
"required": true
}
}
},
"content": {
"type": "md",
"data": "# ${variables.retainerTitle}\n\nService agreement between provider and client."
},
"execution": {
"initialize": {
"initialState": "AWAITING_PAYMENT",
"data": {}
},
"states": {
"AWAITING_PAYMENT": {
"description": "Waiting for initial payment proof."
},
"WORK_IN_PROGRESS": {
"description": "Provider is performing the service."
}
},
"inputs": {
"submitInitialPaymentProof": {
"issuer": {
"type": "participant",
"variable": "clientRepresentative"
},
"schema": {
"paymentReference": {
"type": "string",
"validation": {
"required": true
}
}
}
}
},
"transitions": [
{
"from": "AWAITING_PAYMENT",
"to": "WORK_IN_PROGRESS",
"conditions": [
{
"input": "submitInitialPaymentProof"
}
]
}
]
}
}
'const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
metadata: {templateId: 'did:template:service-retainer-v0-1', name: 'Service Retainer'},
variables: {
serviceProviderRepresentative: {type: 'address', subtype: 'participant', validation: {required: true}},
clientRepresentative: {type: 'address', subtype: 'participant', validation: {required: true}},
retainerTitle: {type: 'string', validation: {required: true}}
},
content: {
type: 'md',
data: '# ${variables.retainerTitle}\n\nService agreement between provider and client.'
},
execution: {
initialize: {initialState: 'AWAITING_PAYMENT', data: {}},
states: {
AWAITING_PAYMENT: {description: 'Waiting for initial payment proof.'},
WORK_IN_PROGRESS: {description: 'Provider is performing the service.'}
},
inputs: {
submitInitialPaymentProof: {
issuer: {type: 'participant', variable: 'clientRepresentative'},
schema: {paymentReference: {type: 'string', validation: {required: true}}}
}
},
transitions: [
{
from: 'AWAITING_PAYMENT',
to: 'WORK_IN_PROGRESS',
conditions: [{input: 'submitInitialPaymentProof'}]
}
]
}
})
};
fetch('https://test-api.shodai.network/v0/agreements/validate-template', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"data": {
"templateId": "did:template:service-retainer-v0-1",
"participantVariableKeys": [
"serviceProviderRepresentative",
"clientRepresentative"
],
"inputIds": [
"submitInitialPaymentProof"
],
"stateIds": [
"AWAITING_PAYMENT",
"WORK_IN_PROGRESS"
],
"warnings": []
},
"meta": {
"apiVersion": "v0",
"requestId": "req_123"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API key",
"requestId": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API key",
"requestId": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API key",
"requestId": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API key",
"requestId": "<string>",
"details": "<unknown>"
}
}
This endpoint checks authored agreement JSON only. It does not validate deployment values, participant wallet mappings, signer, or permit data. Generated API examples document request and response shape; complete deployable agreement JSON lives in /examples/simple and /examples/complex.
Authorizations
Canonical API-key credential. Send X-API-Key: cns_pk_..., or Authorization: Bearer cns_pk_... only as an API-key compatibility alias. OAuth and JWT bearer tokens are not supported.
Body
application/json
Authored agreement JSON to validate before deployment preflight.
Response
Agreement structure validation summary.
Show child attributes
Show child attributes
Example:
{ "templateId": "did:template:service-retainer-v0-1", "participantVariableKeys": [ "serviceProviderRepresentative", "clientRepresentative" ], "inputIds": ["submitInitialPaymentProof"], "stateIds": ["AWAITING_PAYMENT", "WORK_IN_PROGRESS"], "warnings": [] }
Show child attributes
Show child attributes
Was this page helpful?
⌘I