HTTP + JSON
REST endpoints
A small, opinionated REST surface alongside the GraphQL endpoint. Useful for build-time scripts, static-site generators, and pipelines that prefer plain HTTP over a query language.
Interactive reference
Prefer an interactive viewer with a live key verifier?
The /implement/api-reference page renders every /api/v1/* endpoint as a card with parameters, status codes, curl examples, and a paste-your-key panel that verifies against GET /api/v1/me. The full OpenAPI 3.1 specification is served from /api/v1/openapi.jsonand is ready for openapi-generator, Stainless, Speakeasy, Fern, or any OAS 3.1 toolchain.
Namespace
All CASRAI REST endpoints live under a single namespace served by the WordPress REST API. The full root URL is:
https://casrai.org/wp-json/casrai/v1/
http://localhost/casrai/wp-json/casrai/v1/
The REST surface is a deliberately narrow companion to the GraphQL endpoint. Where GraphQL is preferred for ad-hoc field selection and federated traversal, the REST endpoints provide stable, cacheable URLs suitable for static builds and curl-driven workflows.
Authentication
Read endpoints are public. Write endpoints accept WordPress Application Passwords using HTTP Basic authentication (see the WordPress documentation on Application Passwords, introduced in 5.6). Application Passwords are issued per-user from the WordPress admin and can be revoked individually.
Authorization: Basic $(echo -n "username:application_password" | base64)
Endpoint: /dictionary-term
Returns a single dictionary term by slug, or a paged list. The response shape mirrors the fields exposed by the WordPress custom post type, including operational definition, examples, counter-examples, aliases, canonical URI, status, and version.
curl -sS "https://casrai.org/wp-json/casrai/v1/dictionary-term?slug=genai-disclosure" \ -H "Accept: application/json"
{
"id": 4218,
"slug": "genai-disclosure",
"title": "GenAI disclosure",
"status": "stable",
"version": "v2026.1",
"canonical_uri": "https://casrai.org/dictionary/genai-disclosure",
"definition_operational": "A structured statement attached to a research output declaring the use of generative AI tools, the model and version, the human author's role, and the scope of AI-assisted content.",
"examples": ["Manuscript declares use of GPT-4 for copy-editing."],
"counter_examples": ["Author lists 'ChatGPT' as a co-author."],
"aliases": ["AI disclosure", "Generative AI statement"],
"dictionary_domains": [
{ "slug": "genai-disclosure", "name": "GenAI disclosure", "track": "core" }
],
"relationships": [
{ "type": "related", "target_slug": "authorship", "note": "Co-located disclosure block" }
]
}Listing supports paging via per_page (default 20, max 100), page, and a domain query parameter that filters by dictionary domain slug.
curl -sS "https://casrai.org/wp-json/casrai/v1/dictionary-term?domain=research-integrity&per_page=50&page=1"
Endpoint: /object-template
Object templates describe composite metadata records — a Person record, a Project record, a Grant record — as ordered sets of fields. Each field declares a name, a primitive type, a required flag, and either a picklist slug or a dictionary term slug for its value space.
curl -sS "https://casrai.org/wp-json/casrai/v1/object-template?slug=person-affiliation"
{
"id": 8842,
"slug": "person-affiliation",
"title": "Person affiliation",
"canonical_uri": "https://casrai.org/dictionary/object/person-affiliation",
"legacy_source": "CASRAI dictionary v1 (2018)",
"fields": [
{ "name": "person", "type": "reference", "required": true, "dictionary_term_slug": "person" },
{ "name": "organisation","type": "reference", "required": true, "dictionary_term_slug": "organisation" },
{ "name": "role", "type": "enum", "required": false, "picklist_slug": "affiliation-role-types" },
{ "name": "start_date", "type": "date", "required": false },
{ "name": "end_date", "type": "date", "required": false }
]
}Endpoint: /picklist
Picklists are controlled value sets — countries, language codes, contributor types, output types — that constrain a field on an object template. Each list returns its values as an array of strings (or string/identifier pairs where the picklist is identifier-backed).
curl -sS "https://casrai.org/wp-json/casrai/v1/picklist?slug=output-types"
{
"id": 6112,
"slug": "output-types",
"title": "Research output types",
"canonical_uri": "https://casrai.org/dictionary/picklist/output-types",
"legacy_source": "COAR Resource Types v3.1 cross-walk",
"picklist_values": [
"Journal article",
"Book chapter",
"Conference paper",
"Dataset",
"Software",
"Preprint",
"Thesis",
"Report"
]
}Endpoint: /dictionary/stats
A small read-only endpoint returning counts and the last-modified timestamp for the dictionary as a whole. Useful for status badges, cache-warming scripts, and dashboard widgets that need a cheap "did anything change?" probe.
curl -sS "https://casrai.org/wp-json/casrai/v1/dictionary/stats"
{
"terms": { "total": 1284, "stable": 1108, "draft": 142, "deprecated": 34 },
"object_templates": { "total": 96 },
"picklists": { "total": 211 },
"domains": { "total": 20 },
"last_modified": "2026-05-12T14:08:27Z",
"release": "v2026.1"
}Caching and rate limits
Read endpoints set Cache-Control: public, max-age=300, s-maxage=900 and emit an ETag per response. The Cloudflare edge in front of the origin honours both. Default rate limit is 60 requests per minute per IP for unauthenticated clients and 300 per minute per token for authenticated ones; the limits match those documented on the GraphQL endpoint.
Errors
The endpoints return standard HTTP status codes and a JSON error body shaped like the WordPress REST API: { "code": "...", "message": "...", "data": { "status": 404 } }.
API v1 Reference
The /api/v1/ namespace is the bearer-gated companion to the public WP REST surface above. All seven endpoints share a single authentication scheme (HTTP Bearer using a CASRAI plaintext key issued from Account → API keys), a single rate limit (60 requests per minute per key, sliding 60-second window), and a single response style (JSON with explicit X-RateLimit-* headers on every reply).
https://casrai.org/api/v1/
Authorization: Bearer casrai_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Authentication errors
401 missing_authorization— noAuthorizationheader was sent.401 invalid_key_format— the bearer token does not start withcasrai_pk_.401 invalid_or_revoked_key— the key hash does not match any active key.403 insufficient_scope— the endpoint requireswritebut the key isread.429 rate_limit_exceeded— more than 60 requests in the rolling minute. InspectRetry-After.503 auth_backend_unavailable— the verification backend (WP) is temporarily unreachable.
GET /api/v1
Discovery document. Authentication is optional — sending a valid key returns an authenticated block reflecting the resolved identity.
curl https://casrai.org/api/v1
GET /api/v1/me
Returns { user_id, orcid_id, scope, key_prefix, api_version } for the key on the request.
curl -H "Authorization: Bearer $CASRAI_API_KEY" \
https://casrai.org/api/v1/me{
"user_id": 1429,
"orcid_id": "0000-0002-1825-0097",
"scope": "read",
"key_prefix": "casrai_pk_a3f201bc",
"api_version": "v1"
}GET /api/v1/credit/roles
Lists all 14 CRediT roles in canonical order (ANSI/NISO Z39.104-2022).
curl -H "Authorization: Bearer $CASRAI_API_KEY" \
https://casrai.org/api/v1/credit/roles{
"version": "v2022.1",
"standard": "ANSI/NISO Z39.104-2022",
"license": "CC-BY-4.0",
"count": 14,
"roles": [
{
"slug": "conceptualization",
"name": "Conceptualization",
"definition": "Ideas; formulation or evolution of overarching research goals and aims.",
"group": "Planning & design",
"order": 1
}
]
}GET /api/v1/credit/roles/{slug}
Returns a single CRediT role with its canonical URI. 404 if the slug is not one of the 14 NISO roles.
curl -H "Authorization: Bearer $CASRAI_API_KEY" \
https://casrai.org/api/v1/credit/roles/conceptualizationGET /api/v1/dictionary/terms
Paginated list of dictionary terms. Optional query parameters: domain (slug exact-match), limit (1–100, default 20), offset (default 0), search (substring match on slug and title, case-insensitive). Results are returned in deterministic alphabetical order by slug to make pagination stable.
curl -H "Authorization: Bearer $CASRAI_API_KEY" \
"https://casrai.org/api/v1/dictionary/terms?domain=knowledge-equity&limit=20&offset=0"{
"count": 47,
"limit": 20,
"offset": 0,
"results": [
{
"slug": "open-access",
"title": "Open access",
"domain_slug": "knowledge-equity",
"domain_name": "Knowledge equity",
"track": "core",
"status": "stable",
"operational_definition": "...",
"canonical_uri": "https://casrai.org/dictionary/term/open-access"
}
],
"filters": { "domain": "knowledge-equity", "search": null }
}GET /api/v1/dictionary/terms/{slug}
Full term record including examples, counter-examples, aliases, status, version, domain, and relationships.
curl -H "Authorization: Bearer $CASRAI_API_KEY" \
https://casrai.org/api/v1/dictionary/terms/genai-disclosureGET /api/v1/contributions
Lists the bearer key owner's previously-claimed CRediT contributions, sourced from the ORCID-linked WordPress record.
curl -H "Authorization: Bearer $CASRAI_API_KEY" \
https://casrai.org/api/v1/contributionsPOST /api/v1/contributions
Creates a CRediT contribution claim against the bearer key owner's ORCID iD. Requires the write scope — a read-only key returns 403 insufficient_scope. Roles must be a non-empty subset of the 14 CRediT slugs (see /api/v1/credit/roles).
curl -X POST https://casrai.org/api/v1/contributions \
-H "Authorization: Bearer $CASRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"doi": "10.1234/example.2026.0001",
"title": "An open standards approach to research administration",
"journal": "Research Policy",
"date_published": "2026-04-12",
"roles": ["conceptualization", "writing-original-draft"]
}'{
"ok": true,
"user_id": 1429,
"orcid_id": "0000-0002-1825-0097",
"contribution": {
"put_code": 123456,
"doi": "10.1234/example.2026.0001",
"roles": ["conceptualization", "writing-original-draft"],
"pushed_at": "2026-05-21T11:14:02Z"
}
}Rate-limit headers
Every /api/v1/* response includes:
X-RateLimit-Limit— fixed at60.X-RateLimit-Remaining— requests remaining in the current 60-second window.X-RateLimit-Reset— Unix timestamp at which the window resets.Retry-After— seconds until retry, on429only.
CORS
The v1 endpoints set Access-Control-Allow-Origin: * and accept Authorization and Content-Type headers across origins. Pre-flight OPTIONS returns 204. All responses are application/json with charset=utf-8.
When to prefer REST over GraphQL
- Build-time fetches in a static site generator that does not bundle a GraphQL client.
- Shell pipelines or CI jobs driven by curl and jq.
- Edge functions where a small, cacheable URL outperforms a POST body.
- Status badges, smoke tests, and uptime probes against
/dictionary/stats.
For everything else — selecting nested fields, traversing relationships in a single round-trip, writing or proposing terms — see the GraphQL endpoint, the code examples, and the wider WordPress REST API reference.








