The FtI file format
Draft 0.1. Free to use: CC0.
One JSON file a funder puts on its own website, saying what it funds and how to apply.
Name it fti-manifest.json, put it anywhere on your site, and link it from your funding page. You don't need a portal, an account or a server. Each opportunity inside it is a CommonGrants record (version 0.5.0), so the format reuses existing grant data instead of inventing another schema.
The file at a glance
profileRequired- Always fti.discovery/0.1-draft for this version. Readers report other versions as unsupported instead of guessing.
canonicalUrlRequired- The https address where this file lives.
publisherRequired- name and official https website of the funder publishing the file, or the team publishing it on the funder's behalf.
revisionRequired- Any text you choose. Change it every time the file changes.
scopeRequired- id, description and completeness (complete, partial or unknown) of what this file lists. A partial list doesn't mean you have nothing else.
reviewOptional- reviewedOn: the date someone actually checked the information. reviewDueOn: when you plan to check again. Leave them out if you don't know.
prioritiesOptional- text and guidanceUrl describing what you want to fund and what you don't. Priorities are never an open call.
entriesRequired- A list of what you fund: opportunities, programmes or references to other pages. It may be empty.
extensionsOptional- Your own extra data, under keys with a dot, such as org.example.notes. Readers keep it but never treat it as an eligibility rule.
Entries
Every entry has an entryId that you never reuse for a different call, a kind, and a guidanceUrl pointing to your official page.
opportunity- A call you can apply to. It carries a CommonGrants record: either the record itself, or the https address of one.
programme- A programme described in words, with a title, without claiming there's an open call.
source_reference- A title and a link to your official page, when you can't describe the opportunity in structured form yet.
Intake: can people apply?
Add intake to say plainly whether and how you accept applications. Leaving it out means "unknown", never "open to everyone".
mode- public_application, invitation_only, not_accepting or unknown
cadence- fixed_deadline, rolling or unspecified
statement- One plain sentence, for example the deadline with its time zone.
sourceUrl- The official page that says so.
Two more optional fields: applicationUrl, the real application page (not a contact page), and notes, a list of short explanations, each with a sourceUrl.
Opportunities and CommonGrants
An opportunity's commonGrants object has version: "0.5.0" and exactly one of:
record: a CommonGrants OpportunityBase. It needs anid(a UUID),title,description,status,createdAtandlastModifiedAt. Status is an object such as{ "value": "open" }, with the values forecasted, open, closed or custom.url: the https address of a CommonGrants record you already publish. Readers treat it as unchecked until they fetch it.
Put amounts, dates, applicant types and funders in the CommonGrants fields, not in a second copy elsewhere in the file. Rolling and invitation-only intake belong in intake, not in the CommonGrants status.
Known issue: CommonGrants 0.5.0 rejects clock times without a time zone, such as 17:00:00. Give an offset, or state the deadline in the intake statement.
A short example
A fictional funder with one open call and one invitation-only programme. It passes the schema and FtI's validator.
{
"profile": "fti.discovery/0.1-draft",
"canonicalUrl": "https://funder.example.org/fti-manifest.json",
"publisher": {
"name": "Example Foundation (fictional)",
"website": "https://funder.example.org/"
},
"revision": "2026-11-11.1",
"scope": {
"id": "open-source-programmes",
"description": "Our open-source maintenance programmes",
"completeness": "complete"
},
"review": {
"reviewedOn": "2026-11-11",
"reviewDueOn": "2027-02-11"
},
"priorities": {
"text": "We fund maintenance of shared digital infrastructure. We don't fund new startups.",
"guidanceUrl": "https://funder.example.org/what-we-fund"
},
"entries": [
{
"entryId": "maintenance-2026",
"kind": "opportunity",
"guidanceUrl": "https://funder.example.org/maintenance-2026",
"commonGrants": {
"version": "0.5.0",
"record": {
"id": "6f1d2c0a-3b4e-4c5d-9e8f-0a1b2c3d4e5f",
"title": "Maintenance grants 2026",
"description": "Grants for maintainers of widely used open-source tools.",
"status": {
"value": "open"
},
"createdAt": "2026-11-01T09:00:00Z",
"lastModifiedAt": "2026-11-11T09:00:00Z",
"funding": {
"maxAwardAmount": {
"amount": "40000.00",
"currency": "EUR"
}
}
}
},
"intake": {
"mode": "public_application",
"cadence": "fixed_deadline",
"statement": "Applications close 15 December 2026, 17:00 UTC.",
"sourceUrl": "https://funder.example.org/maintenance-2026"
},
"applicationUrl": "https://funder.example.org/maintenance-2026/apply"
},
{
"entryId": "partnerships",
"kind": "programme",
"title": "Strategic partnerships",
"guidanceUrl": "https://funder.example.org/partnerships",
"intake": {
"mode": "invitation_only",
"cadence": "unspecified",
"statement": "By invitation only. We don't accept unsolicited proposals.",
"sourceUrl": "https://funder.example.org/partnerships"
}
}
]
}Evidence and reporting requirements
Optional: say what applicants must show, and what grantees must report.
Add a requirements set to an entry's extensions, under a key that starts with your domain reversed, such as org.example.requirements. If you publish CommonGrants records, you can put it in the record's customFields instead, as a field with fieldType: "object". Use one place for a given set, not both.
profileRequired- Always fti.requirements/0.1-draft.
idRequired- Your ID for this set of requirements, unique within the entry.
revisionRequired- Change it whenever the requirements change.
scopeRequired- phases this set covers, its completeness (complete, partial or unknown), and a one-sentence statement.
sourceRequired- url of the official page the requirements come from, and an optional locator such as a section name.
requirementsRequired- The list of requirements. An empty list only means "nothing required" if the scope is complete and says so.
Each requirement
Every requirement has its own id, plus:
phaseRequired- eligibility, selection, application, post_award_reporting or unspecified.
levelRequired- required, preferred or unknown, as the funder states it.
statementRequired- The requirement in the funder's own words.
evidenceOptional- What counts as evidence, including how things should be counted, when you say so.
presentationOptional- instructions, accepted mediaTypes (such as application/pdf), and formRef pointing to a real form.
timingOptional- A plain statement, and dueAt only for an exact time with a time zone offset.
appliesWhen, handling, sourceOptional- When the requirement applies, how submitted material is handled, and a more specific source.
Requirements are information for applicants. They don't let anyone collect data, and meeting them doesn't prove impact.
{
"profile": "fti.requirements/0.1-draft",
"id": "maintenance-2026-requirements",
"revision": "1",
"scope": {
"phases": [
"application",
"post_award_reporting"
],
"completeness": "partial",
"statement": "Covers what the application and the final report ask for. Selection criteria are on the programme page."
},
"source": {
"url": "https://funder.example.org/maintenance-2026",
"locator": "Section: What we ask for"
},
"requirements": [
{
"id": "usage-evidence",
"phase": "application",
"level": "required",
"statement": "Show that the tool is used beyond your own team.",
"evidence": "Any of: download counts, projects that depend on it, or statements from users. Say how you counted.",
"presentation": {
"instructions": "Attach a PDF of up to two pages.",
"mediaTypes": [
"application/pdf"
]
}
},
{
"id": "final-report",
"phase": "post_award_reporting",
"level": "required",
"statement": "Send a final report on what the grant paid for and what changed.",
"timing": {
"statement": "Due three months after the grant ends."
}
}
]
}Rules readers follow
- Missing information is unknown, not permission to apply.
- Funding priorities are not open calls.
- Past awards don't mean applications are open now.
- If your page and your file disagree, readers show the conflict instead of picking the more favourable answer.
- Unknown fields are rejected, except under
extensions.
Checking a file
The schemas check the file's shape: the file and requirements sets. Any JSON Schema 2020-12 validator can use them, as long as it can load the CommonGrants schemas they link to. FtI's own validator also checks that entry IDs are unique and that a review is not due before it happened. A validator you can use in the browser is planned. Until then, send us your file and we'll check it.
The spec text, schema and examples are dedicated to the public domain under CC0 1.0. CommonGrants is a separate project; FtI links to its schemas and is not endorsed by it.