curl --request POST \
--url https://test-api.shodai.network/v0/agreements/validate \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"agreement": {
"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"
}
]
}
]
}
},
"chainId": 59141
}
'const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
agreement: {
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'}]
}
]
}
},
chainId: 59141
})
};
fetch('https://test-api.shodai.network/v0/agreements/validate', 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"
],
"participants": [
{
"variableKey": "serviceProviderRepresentative",
"walletAddress": "0x1111111111111111111111111111111111111111"
},
{
"variableKey": "clientRepresentative",
"walletAddress": "0x2222222222222222222222222222222222222222",
"email": "client@example.com"
}
],
"observers": [
"legal@example.com"
],
"variables": {
"serviceProviderRepresentative": "0x1111111111111111111111111111111111111111",
"clientRepresentative": "0x2222222222222222222222222222222222222222",
"retainerTitle": "Advisory Retainer"
},
"contributors": [
"0x1111111111111111111111111111111111111111",
"0x2222222222222222222222222222222222222222"
],
"warnings": []
},
"meta": {
"apiVersion": "v0",
"requestId": "req_123"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API credential",
"requestId": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API credential",
"requestId": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API credential",
"requestId": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API credential",
"requestId": "<string>",
"details": "<unknown>"
}
}Preflight deployment request
Checks whether authored agreement JSON plus target chain, deployment values, participant wallet mappings, and observer context are ready for deployment. This does not deploy the agreement.
curl --request POST \
--url https://test-api.shodai.network/v0/agreements/validate \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"agreement": {
"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"
}
]
}
]
}
},
"chainId": 59141
}
'const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
agreement: {
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'}]
}
]
}
},
chainId: 59141
})
};
fetch('https://test-api.shodai.network/v0/agreements/validate', 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"
],
"participants": [
{
"variableKey": "serviceProviderRepresentative",
"walletAddress": "0x1111111111111111111111111111111111111111"
},
{
"variableKey": "clientRepresentative",
"walletAddress": "0x2222222222222222222222222222222222222222",
"email": "client@example.com"
}
],
"observers": [
"legal@example.com"
],
"variables": {
"serviceProviderRepresentative": "0x1111111111111111111111111111111111111111",
"clientRepresentative": "0x2222222222222222222222222222222222222222",
"retainerTitle": "Advisory Retainer"
},
"contributors": [
"0x1111111111111111111111111111111111111111",
"0x2222222222222222222222222222222222222222"
],
"warnings": []
},
"meta": {
"apiVersion": "v0",
"requestId": "req_123"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API credential",
"requestId": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API credential",
"requestId": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API credential",
"requestId": "<string>",
"details": "<unknown>"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing API credential",
"requestId": "<string>",
"details": "<unknown>"
}
}testnet API environment supports Linea Sepolia, Ethereum Sepolia, and Base Sepolia; the production API environment supports Linea Mainnet and Base Mainnet. Include the target chainId so preflight, signing, and deploy-with-permit requests all use the same supported chain. In SDK integrations, prefer client.validateDeployment(...) before deployAgreementWithPermit(...). 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.
Body
Deployment preflight request for authored agreement JSON and its deployment context.
Authored agreement JSON to preflight before deployment.
Supported agreement deployment chain ID to preflight. Use the same value when signing and submitting the deploy-with-permit request.
Deployment values for variables required when the agreement is created.
Participant wallet mappings for participant address variables.
Show child attributes
Show child attributes
Optional observer email addresses to associate with the agreement record.
Response
Deployment preflight summary.
Show child attributes
Show child attributes
{ "templateId": "did:template:service-retainer-v0-1", "participantVariableKeys": [ "serviceProviderRepresentative", "clientRepresentative" ], "participants": [ { "variableKey": "serviceProviderRepresentative", "walletAddress": "0x1111111111111111111111111111111111111111" }, { "variableKey": "clientRepresentative", "walletAddress": "0x2222222222222222222222222222222222222222", "email": "client@example.com" } ], "observers": ["legal@example.com"], "variables": { "serviceProviderRepresentative": "0x1111111111111111111111111111111111111111", "clientRepresentative": "0x2222222222222222222222222222222222222222", "retainerTitle": "Advisory Retainer" }, "contributors": [ "0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222" ], "warnings": [] }
Show child attributes
Show child attributes
Was this page helpful?