Grant Compliance API Documentation
Read supplied grant guidelines, application text, budgets, and evidence. Requirements, eligibility, totals, and reporting gaps are checked only against rules and documents in the request. Nothing is marked officially approved or compliant. Payment is the exact USDC price on Base with x402.
https://brainiac.software/api/v1/grant-compliance/grant-requirements-extract$0.04 USDCExtract grant requirements
Read Requirement lines and structured requirements. Other prose is not turned into a grant rule.
Body
| Field | Required | Notes |
|---|---|---|
guidelines | No | string |
requirements | No | array; Array |
Request exampleJSON
{
"guidelines": "Requirement: R1 | The applicant must be a registered charity.\nRequirement: R2 | The project must serve London.\nApplicants should consider a strong title.\n"
}Response exampleJSON
{
"checkedAt": "2026-11-02T19:00:00.000Z",
"officialApproval": false,
"complianceDetermined": false,
"status": "extracted",
"requirements": [
{
"id": "R1",
"text": "The applicant must be a registered charity.",
"source": "guidelines"
},
{
"id": "R2",
"text": "The project must serve London.",
"source": "guidelines"
}
],
"findings": [],
"limitations": [
"This is not an official approval, and compliance was not determined.",
"Rules, eligibility criteria, budgets, and evidence are used only when they are supplied in the request.",
"Labeled lines are read as written. Unlabeled prose is not turned into a grant rule.",
"A matching evidence id does not judge whether the evidence is sufficient."
]
}cURL
curl -i -X POST "https://brainiac.software/api/v1/grant-compliance/grant-requirements-extract" \
-H 'content-type: application/json' \
-H 'Idempotency-Key: <fresh-64-character-random-hex-key>' \
--data-binary @- <<'JSON'
{
"guidelines": "Requirement: R1 | The applicant must be a registered charity.\nRequirement: R2 | The project must serve London.\nApplicants should consider a strong title.\n"
}
JSONhttps://brainiac.software/api/v1/grant-compliance/grant-eligibility-check$0.04 USDCCheck supplied eligibility rules
Compare each supplied rule with the supplied fact of the same name. A match is not an approval, and missing facts are not filled in.
Body
| Field | Required | Notes |
|---|---|---|
rules | Yes | array; Array |
facts | No | array; Array |
Request exampleJSON
{
"rules": [
{
"id": "org",
"fact": "organisationType",
"operator": "equals",
"value": "charity"
},
{
"id": "years",
"fact": "yearsOperating",
"operator": "number_at_least",
"value": "2"
}
],
"facts": [
{
"name": "organisationType",
"value": "charity"
},
{
"name": "yearsOperating",
"value": "1"
}
]
}Response exampleJSON
{
"checkedAt": "2026-11-02T19:00:00.000Z",
"officialApproval": false,
"complianceDetermined": false,
"status": "not_met",
"results": [
{
"id": "org",
"fact": "organisationType",
"operator": "equals",
"value": "charity",
"factValue": "charity",
"status": "met",
"detail": "The supplied fact matches the supplied value. This is not an approval."
},
{
"id": "years",
"fact": "yearsOperating",
"operator": "number_at_least",
"value": "2",
"factValue": "1",
"status": "not_met",
"detail": "The supplied number does not meet the supplied comparison."
}
],
"findings": [
{
"kind": "observed",
"code": "rules_only",
"detail": "Each rule was supplied in the request. No eligibility criterion was added."
}
],
"limitations": [
"This is not an official approval, and compliance was not determined.",
"Rules, eligibility criteria, budgets, and evidence are used only when they are supplied in the request.",
"Labeled lines are read as written. Unlabeled prose is not turned into a grant rule.",
"A matching evidence id does not judge whether the evidence is sufficient."
]
}cURL
curl -i -X POST "https://brainiac.software/api/v1/grant-compliance/grant-eligibility-check" \
-H 'content-type: application/json' \
-H 'Idempotency-Key: <fresh-64-character-random-hex-key>' \
--data-binary @- <<'JSON'
{
"rules": [
{
"id": "org",
"fact": "organisationType",
"operator": "equals",
"value": "charity"
},
{
"id": "years",
"fact": "yearsOperating",
"operator": "number_at_least",
"value": "2"
}
],
"facts": [
{
"name": "organisationType",
"value": "charity"
},
{
"name": "yearsOperating",
"value": "1"
}
]
}
JSONhttps://brainiac.software/api/v1/grant-compliance/grant-application-completeness$0.04 USDCCheck application completeness
Mark a requirement present only when an application section cites its id. The answer is not scored, and a complete set is not compliance.
Body
| Field | Required | Notes |
|---|---|---|
guidelines | No | string |
requirements | No | array; Array |
applicationText | No | string |
sections | No | array; Array |
Request exampleJSON
{
"requirements": [
{
"id": "R1",
"text": "The applicant must be a registered charity."
},
{
"id": "R2",
"text": "The project must serve London."
}
],
"sections": [
{
"requirementId": "R1",
"text": "We are a registered charity."
}
]
}Response exampleJSON
{
"checkedAt": "2026-11-02T19:00:00.000Z",
"officialApproval": false,
"complianceDetermined": false,
"status": "incomplete",
"items": [
{
"id": "R1",
"text": "The applicant must be a registered charity.",
"status": "present",
"detail": "An application section cited this requirement id. The answer was not scored."
},
{
"id": "R2",
"text": "The project must serve London.",
"status": "missing",
"detail": "No application section cited this requirement id."
}
],
"findings": [],
"limitations": [
"This is not an official approval, and compliance was not determined.",
"Rules, eligibility criteria, budgets, and evidence are used only when they are supplied in the request.",
"Labeled lines are read as written. Unlabeled prose is not turned into a grant rule.",
"A matching evidence id does not judge whether the evidence is sufficient."
]
}cURL
curl -i -X POST "https://brainiac.software/api/v1/grant-compliance/grant-application-completeness" \
-H 'content-type: application/json' \
-H 'Idempotency-Key: <fresh-64-character-random-hex-key>' \
--data-binary @- <<'JSON'
{
"requirements": [
{
"id": "R1",
"text": "The applicant must be a registered charity."
},
{
"id": "R2",
"text": "The project must serve London."
}
],
"sections": [
{
"requirementId": "R1",
"text": "We are a registered charity."
}
]
}
JSONhttps://brainiac.software/api/v1/grant-compliance/grant-budget-validate$0.05 USDCValidate a grant budget
Sum the supplied lines, compare that sum with a supplied total, and check supplied category amount or percent caps. No cap is assumed.
Body
| Field | Required | Notes |
|---|---|---|
currency | No | string |
lines | Yes | array; Array |
total | No | number |
limits | No | array; Array |
Request exampleJSON
{
"currency": "GBP",
"lines": [
{
"category": "staff",
"description": "Coordinator",
"amount": 4000
},
{
"category": "equipment",
"description": "Laptop",
"amount": 1000
}
],
"total": 5000,
"limits": [
{
"category": "staff",
"maxPercent": 40
}
]
}Response exampleJSON
{
"checkedAt": "2026-11-02T19:00:00.000Z",
"officialApproval": false,
"complianceDetermined": false,
"status": "inconsistent",
"currency": "GBP",
"calculatedTotal": 5000,
"statedTotal": 5000,
"lines": [
{
"category": "staff",
"description": "Coordinator",
"amount": 4000
},
{
"category": "equipment",
"description": "Laptop",
"amount": 1000
}
],
"limits": [
{
"category": "staff",
"spent": 4000,
"maxAmount": null,
"maxPercent": 40,
"percent": 80,
"status": "over_limit"
}
],
"findings": [
{
"kind": "observed",
"code": "total_matches",
"detail": "The line amounts sum to 5000, which matches the supplied total."
},
{
"kind": "conflict",
"code": "category_over_limit",
"detail": "staff spent 4000, 80 percent of 5000. The supplied limit was not met. This is not a funding decision."
}
],
"limitations": [
"This is not an official approval, and compliance was not determined.",
"Rules, eligibility criteria, budgets, and evidence are used only when they are supplied in the request.",
"Labeled lines are read as written. Unlabeled prose is not turned into a grant rule.",
"A matching evidence id does not judge whether the evidence is sufficient."
]
}cURL
curl -i -X POST "https://brainiac.software/api/v1/grant-compliance/grant-budget-validate" \
-H 'content-type: application/json' \
-H 'Idempotency-Key: <fresh-64-character-random-hex-key>' \
--data-binary @- <<'JSON'
{
"currency": "GBP",
"lines": [
{
"category": "staff",
"description": "Coordinator",
"amount": 4000
},
{
"category": "equipment",
"description": "Laptop",
"amount": 1000
}
],
"total": 5000,
"limits": [
{
"category": "staff",
"maxPercent": 40
}
]
}
JSONhttps://brainiac.software/api/v1/grant-compliance/grant-expense-eligibility-check$0.04 USDCCheck expenses against supplied rules
Apply only the supplied category decisions. A category with no rule stays not supplied, and an eligible rule is not a funder decision.
Body
| Field | Required | Notes |
|---|---|---|
expenses | Yes | array; Array |
rules | Yes | array; Array |
Request exampleJSON
{
"expenses": [
{
"id": "E1",
"description": "Coordinator salary",
"category": "staff",
"amount": 4000
},
{
"id": "E2",
"description": "Alcohol for launch",
"category": "hospitality",
"amount": 200
}
],
"rules": [
{
"category": "staff",
"decision": "eligible"
},
{
"category": "hospitality",
"decision": "ineligible"
}
]
}Response exampleJSON
{
"checkedAt": "2026-11-02T19:00:00.000Z",
"officialApproval": false,
"complianceDetermined": false,
"status": "excluded_by_rule",
"expenses": [
{
"id": "E1",
"description": "Coordinator salary",
"category": "staff",
"amount": 4000,
"status": "matches_rule",
"detail": "A supplied rule says this category is eligible. This is not a funder decision."
},
{
"id": "E2",
"description": "Alcohol for launch",
"category": "hospitality",
"amount": 200,
"status": "excluded_by_rule",
"detail": "A supplied rule says this category is ineligible. This is not a funder decision."
}
],
"findings": [
{
"kind": "observed",
"code": "expense_rules_only",
"detail": "An expense is excluded only when a supplied rule says that category is ineligible. Other categories stay not supplied."
}
],
"limitations": [
"This is not an official approval, and compliance was not determined.",
"Rules, eligibility criteria, budgets, and evidence are used only when they are supplied in the request.",
"Labeled lines are read as written. Unlabeled prose is not turned into a grant rule.",
"A matching evidence id does not judge whether the evidence is sufficient."
]
}cURL
curl -i -X POST "https://brainiac.software/api/v1/grant-compliance/grant-expense-eligibility-check" \
-H 'content-type: application/json' \
-H 'Idempotency-Key: <fresh-64-character-random-hex-key>' \
--data-binary @- <<'JSON'
{
"expenses": [
{
"id": "E1",
"description": "Coordinator salary",
"category": "staff",
"amount": 4000
},
{
"id": "E2",
"description": "Alcohol for launch",
"category": "hospitality",
"amount": 200
}
],
"rules": [
{
"category": "staff",
"decision": "eligible"
},
{
"category": "hospitality",
"decision": "ineligible"
}
]
}
JSONhttps://brainiac.software/api/v1/grant-compliance/grant-evidence-match$0.05 USDCMatch evidence to requirements
Attach evidence that cites a requirement id. Evidence with no id is not matched, and the strength of the evidence is not judged.
Body
| Field | Required | Notes |
|---|---|---|
requirements | Yes | array; Array |
evidence | No | array; Array |
Request exampleJSON
{
"requirements": [
{
"id": "R1",
"text": "The applicant must be a registered charity."
},
{
"id": "R2",
"text": "The project must serve London."
}
],
"evidence": [
{
"id": "EV1",
"requirementId": "R1",
"text": "Charity Commission number 1234567."
}
]
}Response exampleJSON
{
"checkedAt": "2026-11-02T19:00:00.000Z",
"officialApproval": false,
"complianceDetermined": false,
"status": "incomplete",
"requirements": [
{
"id": "R1",
"text": "The applicant must be a registered charity.",
"status": "matched",
"evidenceIds": [
"EV1"
]
},
{
"id": "R2",
"text": "The project must serve London.",
"status": "missing",
"evidenceIds": []
}
],
"findings": [
{
"kind": "observed",
"code": "evidence_by_id",
"detail": "Evidence matches a requirement only when it cites that requirement id. The text was not judged."
}
],
"limitations": [
"This is not an official approval, and compliance was not determined.",
"Rules, eligibility criteria, budgets, and evidence are used only when they are supplied in the request.",
"Labeled lines are read as written. Unlabeled prose is not turned into a grant rule.",
"A matching evidence id does not judge whether the evidence is sufficient."
]
}cURL
curl -i -X POST "https://brainiac.software/api/v1/grant-compliance/grant-evidence-match" \
-H 'content-type: application/json' \
-H 'Idempotency-Key: <fresh-64-character-random-hex-key>' \
--data-binary @- <<'JSON'
{
"requirements": [
{
"id": "R1",
"text": "The applicant must be a registered charity."
},
{
"id": "R2",
"text": "The project must serve London."
}
],
"evidence": [
{
"id": "EV1",
"requirementId": "R1",
"text": "Charity Commission number 1234567."
}
]
}
JSONhttps://brainiac.software/api/v1/grant-compliance/grant-deliverable-track$0.03 USDCTrack supplied deliverables
Repeat the status supplied for each deliverable and compare an update date with a supplied due date. accepted_by_caller is not an official acceptance.
Body
| Field | Required | Notes |
|---|---|---|
deliverables | Yes | array; Array |
updates | No | array; Array |
Request exampleJSON
{
"deliverables": [
{
"id": "D1",
"name": "Workshop series",
"dueDate": "2026-12-01"
},
{
"id": "D2",
"name": "Evaluation note",
"dueDate": "2027-01-15"
}
],
"updates": [
{
"deliverableId": "D1",
"status": "submitted",
"date": "2026-12-20",
"note": "Workshops delivered."
}
]
}Response exampleJSON
{
"checkedAt": "2026-11-02T19:00:00.000Z",
"officialApproval": false,
"complianceDetermined": false,
"status": "incomplete",
"deliverables": [
{
"id": "D1",
"name": "Workshop series",
"dueDate": "2026-12-01",
"status": "submitted",
"updateDate": "2026-12-20",
"detail": "The supplied update says submitted."
},
{
"id": "D2",
"name": "Evaluation note",
"dueDate": "2027-01-15",
"status": "not_supplied",
"updateDate": "",
"detail": "No update was supplied for this deliverable."
}
],
"findings": [
{
"kind": "observed",
"code": "caller_updates",
"detail": "Deliverable status comes only from the supplied updates. accepted_by_caller is not an official acceptance."
},
{
"kind": "observed",
"code": "late_against_supplied_date",
"detail": "D1 has update date 2026-12-20 after the supplied due date 2026-12-01. No penalty was decided."
}
],
"limitations": [
"This is not an official approval, and compliance was not determined.",
"Rules, eligibility criteria, budgets, and evidence are used only when they are supplied in the request.",
"Labeled lines are read as written. Unlabeled prose is not turned into a grant rule.",
"A matching evidence id does not judge whether the evidence is sufficient."
]
}cURL
curl -i -X POST "https://brainiac.software/api/v1/grant-compliance/grant-deliverable-track" \
-H 'content-type: application/json' \
-H 'Idempotency-Key: <fresh-64-character-random-hex-key>' \
--data-binary @- <<'JSON'
{
"deliverables": [
{
"id": "D1",
"name": "Workshop series",
"dueDate": "2026-12-01"
},
{
"id": "D2",
"name": "Evaluation note",
"dueDate": "2027-01-15"
}
],
"updates": [
{
"deliverableId": "D1",
"status": "submitted",
"date": "2026-12-20",
"note": "Workshops delivered."
}
]
}
JSONhttps://brainiac.software/api/v1/grant-compliance/grant-report-validate$0.04 USDCValidate a grant report
Mark a reporting obligation present only when the report cites its id. A present section is not accepted by a funder.
Body
| Field | Required | Notes |
|---|---|---|
guidelines | No | string |
obligations | No | array; Array |
reportText | No | string |
reportSections | No | array; Array |
Request exampleJSON
{
"obligations": [
{
"id": "REP1",
"text": "State the number of participants."
},
{
"id": "REP2",
"text": "Attach the budget variance."
}
],
"reportSections": [
{
"obligationId": "REP1",
"text": "120 participants attended."
}
]
}Response exampleJSON
{
"checkedAt": "2026-11-02T19:00:00.000Z",
"officialApproval": false,
"complianceDetermined": false,
"status": "incomplete",
"items": [
{
"id": "REP1",
"text": "State the number of participants.",
"status": "present",
"detail": "The report cites this obligation id. The answer was not accepted."
},
{
"id": "REP2",
"text": "Attach the budget variance.",
"status": "missing",
"detail": "The report has no section citing this obligation id."
}
],
"findings": [],
"limitations": [
"This is not an official approval, and compliance was not determined.",
"Rules, eligibility criteria, budgets, and evidence are used only when they are supplied in the request.",
"Labeled lines are read as written. Unlabeled prose is not turned into a grant rule.",
"A matching evidence id does not judge whether the evidence is sufficient."
]
}cURL
curl -i -X POST "https://brainiac.software/api/v1/grant-compliance/grant-report-validate" \
-H 'content-type: application/json' \
-H 'Idempotency-Key: <fresh-64-character-random-hex-key>' \
--data-binary @- <<'JSON'
{
"obligations": [
{
"id": "REP1",
"text": "State the number of participants."
},
{
"id": "REP2",
"text": "Attach the budget variance."
}
],
"reportSections": [
{
"obligationId": "REP1",
"text": "120 participants attended."
}
]
}
JSONhttps://brainiac.software/api/v1/grant-compliance/grant-deadline-extract$0.03 USDCExtract grant deadlines
Read Deadline lines that contain a YYYY-MM-DD date. Other dates in the guidelines are not turned into deadlines.
Body
| Field | Required | Notes |
|---|---|---|
guidelines | Yes | string |
Request exampleJSON
{
"guidelines": "Deadline: application | 2026-06-30 | Application closes\nDeadline: report | 2027-03-31 | Final report is due\nThe narrative mentions 1 January 2020 in passing.\n"
}Response exampleJSON
{
"checkedAt": "2026-11-02T19:00:00.000Z",
"officialApproval": false,
"complianceDetermined": false,
"status": "extracted",
"deadlines": [
{
"id": "application",
"date": "2026-06-30",
"detail": "Application closes"
},
{
"id": "report",
"date": "2027-03-31",
"detail": "Final report is due"
}
],
"findings": [],
"limitations": [
"This is not an official approval, and compliance was not determined.",
"Rules, eligibility criteria, budgets, and evidence are used only when they are supplied in the request.",
"Labeled lines are read as written. Unlabeled prose is not turned into a grant rule.",
"A matching evidence id does not judge whether the evidence is sufficient."
]
}cURL
curl -i -X POST "https://brainiac.software/api/v1/grant-compliance/grant-deadline-extract" \
-H 'content-type: application/json' \
-H 'Idempotency-Key: <fresh-64-character-random-hex-key>' \
--data-binary @- <<'JSON'
{
"guidelines": "Deadline: application | 2026-06-30 | Application closes\nDeadline: report | 2027-03-31 | Final report is due\nThe narrative mentions 1 January 2020 in passing.\n"
}
JSONhttps://brainiac.software/api/v1/grant-compliance/grant-compliance-report$0.12 USDCPrepare a grant compliance report
Combine the supplied requirement, eligibility, budget, evidence, deliverable, and reporting checks. The report does not approve the application or determine compliance.
Body
| Field | Required | Notes |
|---|---|---|
guidelines | No | string |
requirements | No | array; Array |
rules | No | array; Array |
facts | No | array; Array |
applicationText | No | string |
sections | No | array; Array |
currency | No | string |
lines | No | array; Array |
total | No | number |
limits | No | array; Array |
expenses | No | array; Array |
expenseRules | No | array; Array |
evidence | No | array; Array |
deliverables | No | array; Array |
updates | No | array; Array |
obligations | No | array; Array |
reportText | No | string |
reportSections | No | array; Array |
Request exampleJSON
{
"guidelines": "Requirement: R1 | The applicant must be a registered charity.\nRequirement: R2 | The project must serve London.\nDeadline: application | 2026-06-30 | Application closes\nReporting: REP1 | State the number of participants.\nReporting: REP2 | Attach the budget variance.\nApplicants should consider a strong title.\nThe narrative mentions 1 January 2020 in passing.\n",
"rules": [
{
"id": "org",
"fact": "organisationType",
"operator": "equals",
"value": "charity"
},
{
"id": "years",
"fact": "yearsOperating",
"operator": "number_at_least",
"value": "2"
}
],
"facts": [
{
"name": "organisationType",
"value": "charity"
},
{
"name": "yearsOperating",
"value": "1"
}
],
"sections": [
{
"requirementId": "R1",
"text": "We are a registered charity."
}
],
"currency": "GBP",
"lines": [
{
"category": "staff",
"description": "Coordinator",
"amount": 4000
},
{
"category": "equipment",
"description": "Laptop",
"amount": 1000
}
],
"total": 5000,
"limits": [
{
"category": "staff",
"maxPercent": 40
}
],
"expenses": [
{
"id": "E1",
"description": "Coordinator salary",
"category": "staff",
"amount": 4000
},
{
"id": "E2",
"description": "Alcohol for launch",
"category": "hospitality",
"amount": 200
}
],
"expenseRules": [
{
"category": "staff",
"decision": "eligible"
},
{
"category": "hospitality",
"decision": "ineligible"
}
],
"evidence": [
{
"id": "EV1",
"requirementId": "R1",
"text": "Charity Commission number 1234567."
}
],
"deliverables": [
{
"id": "D1",
"name": "Workshop series",
"dueDate": "2026-12-01"
},
{
"id": "D2",
"name": "Evaluation note",
"dueDate": "2027-01-15"
}
],
"updates": [
{
"deliverableId": "D1",
"status": "submitted",
"date": "2026-12-20",
"note": "Workshops delivered."
}
],
"reportSections": [
{
"obligationId": "REP1",
"text": "120 participants attended."
}
]
}Response exampleJSON
{
"checkedAt": "2026-11-02T19:00:00.000Z",
"officialApproval": false,
"complianceDetermined": false,
"summary": "This report repeats supplied rules and documents. It is not an official approval and does not determine compliance.",
"requirements": {
"status": "extracted",
"count": 2
},
"eligibility": {
"status": "not_met",
"met": 1,
"notMet": 1,
"notSupplied": 0
},
"application": {
"status": "incomplete",
"missing": 1
},
"budget": {
"status": "inconsistent",
"currency": "GBP",
"calculatedTotal": 5000,
"statedTotal": 5000,
"overLimit": 1
},
"expenses": {
"status": "excluded_by_rule",
"excluded": 1
},
"evidence": {
"status": "incomplete",
"unmatched": 1
},
"deliverables": {
"status": "incomplete",
"late": 1,
"notSupplied": 1
},
"reporting": {
"status": "incomplete",
"missing": 1
},
"deadlines": {
"status": "extracted",
"count": 1
},
"findings": [
{
"kind": "observed",
"code": "rules_only",
"detail": "Each rule was supplied in the request. No eligibility criterion was added."
},
{
"kind": "observed",
"code": "total_matches",
"detail": "The line amounts sum to 5000, which matches the supplied total."
},
{
"kind": "conflict",
"code": "category_over_limit",
"detail": "staff spent 4000, 80 percent of 5000. The supplied limit was not met. This is not a funding decision."
},
{
"kind": "observed",
"code": "expense_rules_only",
"detail": "An expense is excluded only when a supplied rule says that category is ineligible. Other categories stay not supplied."
},
{
"kind": "observed",
"code": "evidence_by_id",
"detail": "Evidence matches a requirement only when it cites that requirement id. The text was not judged."
},
{
"kind": "observed",
"code": "caller_updates",
"detail": "Deliverable status comes only from the supplied updates. accepted_by_caller is not an official acceptance."
},
{
"kind": "observed",
"code": "late_against_supplied_date",
"detail": "D1 has update date 2026-12-20 after the supplied due date 2026-12-01. No penalty was decided."
},
{
"kind": "unavailable",
"code": "not_an_approval",
"detail": "No grant rule, eligibility result, or approval outcome was invented. This report does not determine compliance."
}
],
"limitations": [
"This is not an official approval, and compliance was not determined.",
"Rules, eligibility criteria, budgets, and evidence are used only when they are supplied in the request.",
"Labeled lines are read as written. Unlabeled prose is not turned into a grant rule.",
"A matching evidence id does not judge whether the evidence is sufficient."
]
}cURL
curl -i -X POST "https://brainiac.software/api/v1/grant-compliance/grant-compliance-report" \
-H 'content-type: application/json' \
-H 'Idempotency-Key: <fresh-64-character-random-hex-key>' \
--data-binary @- <<'JSON'
{
"guidelines": "Requirement: R1 | The applicant must be a registered charity.\nRequirement: R2 | The project must serve London.\nDeadline: application | 2026-06-30 | Application closes\nReporting: REP1 | State the number of participants.\nReporting: REP2 | Attach the budget variance.\nApplicants should consider a strong title.\nThe narrative mentions 1 January 2020 in passing.\n",
"rules": [
{
"id": "org",
"fact": "organisationType",
"operator": "equals",
"value": "charity"
},
{
"id": "years",
"fact": "yearsOperating",
"operator": "number_at_least",
"value": "2"
}
],
"facts": [
{
"name": "organisationType",
"value": "charity"
},
{
"name": "yearsOperating",
"value": "1"
}
],
"sections": [
{
"requirementId": "R1",
"text": "We are a registered charity."
}
],
"currency": "GBP",
"lines": [
{
"category": "staff",
"description": "Coordinator",
"amount": 4000
},
{
"category": "equipment",
"description": "Laptop",
"amount": 1000
}
],
"total": 5000,
"limits": [
{
"category": "staff",
"maxPercent": 40
}
],
"expenses": [
{
"id": "E1",
"description": "Coordinator salary",
"category": "staff",
"amount": 4000
},
{
"id": "E2",
"description": "Alcohol for launch",
"category": "hospitality",
"amount": 200
}
],
"expenseRules": [
{
"category": "staff",
"decision": "eligible"
},
{
"category": "hospitality",
"decision": "ineligible"
}
],
"evidence": [
{
"id": "EV1",
"requirementId": "R1",
"text": "Charity Commission number 1234567."
}
],
"deliverables": [
{
"id": "D1",
"name": "Workshop series",
"dueDate": "2026-12-01"
},
{
"id": "D2",
"name": "Evaluation note",
"dueDate": "2027-01-15"
}
],
"updates": [
{
"deliverableId": "D1",
"status": "submitted",
"date": "2026-12-20",
"note": "Workshops delivered."
}
],
"reportSections": [
{
"obligationId": "REP1",
"text": "120 participants attended."
}
]
}
JSON