Skip to main content
v2026.1714 entries · CC-BY 4.0

Copy-paste patterns

Code examples

Worked samples in JavaScript, Python, and PHP for the three integrations most teams build first: fetch a term, render JSON-LD, build a CRediT statement.

Pattern 1 — Fetch a dictionary term

Read a single term by slug from the GraphQL endpoint. The same call works against the production endpoint and the local development endpoint; only the URL changes.

JavaScript (browser or Node 18+)
javascript
const ENDPOINT = "https://casrai.org/graphql";

async function fetchTerm(slug) {
  const res = await fetch(ENDPOINT, {
    method:  "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      query: `
        query GetTerm($slug: ID!) {
          dictionaryTerm(id: $slug, idType: SLUG) {
            slug title status version canonicalUri
            definitionOperational
            examples counterExamples aliases
            dictionaryDomains { nodes { slug name } }
          }
        }
      `,
      variables: { slug },
    }),
  });
  const { data, errors } = await res.json();
  if (errors) throw new Error(errors[0].message);
  return data.dictionaryTerm;
}

const term = await fetchTerm("research-integrity");
console.log(`${term.title} (${term.status}, ${term.version})`);
console.log(term.definitionOperational);
Python 3.10+ (requests)
python
import requests

ENDPOINT = "https://casrai.org/graphql"

QUERY = """
query GetTerm($slug: ID!) {
  dictionaryTerm(id: $slug, idType: SLUG) {
    slug title status version canonicalUri
    definitionOperational
    examples counterExamples aliases
    dictionaryDomains { nodes { slug name } }
  }
}
"""

def fetch_term(slug: str) -> dict:
    r = requests.post(
        ENDPOINT,
        json={"query": QUERY, "variables": {"slug": slug}},
        timeout=10,
    )
    r.raise_for_status()
    payload = r.json()
    if payload.get("errors"):
        raise RuntimeError(payload["errors"][0]["message"])
    return payload["data"]["dictionaryTerm"]

term = fetch_term("research-integrity")
print(f"{term['title']} ({term['status']}, {term['version']})")
print(term["definitionOperational"])
PHP 8.1+ (curl, no Composer dependency)
php
<?php
declare(strict_types=1);

const CASRAI_ENDPOINT = "https://casrai.org/graphql";

function casrai_fetch_term(string $slug): array {
    $query = <<<'GQL'
        query GetTerm($slug: ID!) {
          dictionaryTerm(id: $slug, idType: SLUG) {
            slug title status version canonicalUri
            definitionOperational
            examples counterExamples aliases
            dictionaryDomains { nodes { slug name } }
          }
        }
        GQL;

    $body = json_encode(["query" => $query, "variables" => ["slug" => $slug]]);

    $ch = curl_init(CASRAI_ENDPOINT);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => ["Content-Type: application/json"],
        CURLOPT_POSTFIELDS     => $body,
        CURLOPT_TIMEOUT        => 10,
    ]);
    $raw = curl_exec($ch);
    curl_close($ch);

    $payload = json_decode($raw, true);
    if (!empty($payload["errors"])) {
        throw new RuntimeException($payload["errors"][0]["message"]);
    }
    return $payload["data"]["dictionaryTerm"];
}

$term = casrai_fetch_term("research-integrity");
echo "{$term['title']} ({$term['status']}, {$term['version']})\n";
echo $term["definitionOperational"], "\n";

Pattern 2 — Render JSON-LD for a term

Emit a Schema.org-aligned DefinedTerm payload for a dictionary record, suitable for embedding in a page‘s <script type="application/ld+json"> block. See CRediT in JSON-LD for the schema rationale.

JavaScript — DefinedTerm builder
javascript
function termToJsonLd(term) {
  return {
    "@context":         "https://schema.org",
    "@type":            "DefinedTerm",
    "@id":              term.canonicalUri,
    name:               term.title,
    identifier:         term.canonicalUri,
    description:        term.definitionOperational,
    inDefinedTermSet:   "https://casrai.org/dictionary",
    url:                term.canonicalUri,
    sameAs:             term.aliases ?? [],
    license:            "https://creativecommons.org/licenses/by/4.0/",
  };
}

const jsonLd = termToJsonLd(await fetchTerm("research-integrity"));
process.stdout.write(JSON.stringify(jsonLd, null, 2));
Python — DefinedTerm builder
python
import json

def term_to_jsonld(term: dict) -> dict:
    return {
        "@context":         "https://schema.org",
        "@type":            "DefinedTerm",
        "@id":              term["canonicalUri"],
        "name":             term["title"],
        "identifier":       term["canonicalUri"],
        "description":      term["definitionOperational"],
        "inDefinedTermSet": "https://casrai.org/dictionary",
        "url":              term["canonicalUri"],
        "sameAs":           term.get("aliases") or [],
        "license":          "https://creativecommons.org/licenses/by/4.0/",
    }

print(json.dumps(term_to_jsonld(fetch_term("research-integrity")), indent=2))
PHP — DefinedTerm builder
php
<?php
function term_to_jsonld(array $term): array {
    return [
        "@context"         => "https://schema.org",
        "@type"            => "DefinedTerm",
        "@id"              => $term["canonicalUri"],
        "name"             => $term["title"],
        "identifier"       => $term["canonicalUri"],
        "description"      => $term["definitionOperational"],
        "inDefinedTermSet" => "https://casrai.org/dictionary",
        "url"              => $term["canonicalUri"],
        "sameAs"           => $term["aliases"] ?? [],
        "license"          => "https://creativecommons.org/licenses/by/4.0/",
    ];
}

echo json_encode(
    term_to_jsonld(casrai_fetch_term("research-integrity")),
    JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
);

Pattern 3 — Build a CRediT contributor statement

Given a list of contributors with their CRediT roles, produce the human-readable "Author contributions" paragraph that most journals expect alongside the structured JATS markup. Each role is rendered with the canonical wording and the optional degree.

JavaScript — author-contributions paragraph
javascript
/**
 * contributors: [
 *   { name: "San Zhang", roles: [
 *       { slug: "conceptualization" },
 *       { slug: "software", degree: "lead" }
 *   ]}
 * ]
 */
const ROLE_LABELS = {
  "conceptualization":        "Conceptualization",
  "data-curation":            "Data curation",
  "formal-analysis":          "Formal analysis",
  "funding-acquisition":      "Funding acquisition",
  "investigation":            "Investigation",
  "methodology":              "Methodology",
  "project-administration":   "Project administration",
  "resources":                "Resources",
  "software":                 "Software",
  "supervision":              "Supervision",
  "validation":               "Validation",
  "visualization":            "Visualization",
  "writing-original-draft":   "Writing - original draft",
  "writing-review-editing":   "Writing - review & editing",
};

function buildCreditStatement(contributors) {
  return contributors.map(({ name, roles }) => {
    const parts = roles.map(r => {
      const label = ROLE_LABELS[r.slug] ?? r.slug;
      return r.degree ? `${label} (${r.degree})` : label;
    });
    return `${name}: ${parts.join("; ")}.`;
  }).join(" ");
}

console.log(buildCreditStatement([
  { name: "San Zhang", roles: [
      { slug: "conceptualization" },
      { slug: "software", degree: "lead" },
      { slug: "writing-original-draft", degree: "supporting" },
  ]},
  { name: "Mei Liu", roles: [
      { slug: "investigation", degree: "lead" },
      { slug: "formal-analysis" },
  ]},
]));
Python — author-contributions paragraph
python
ROLE_LABELS = {
    "conceptualization":      "Conceptualization",
    "data-curation":          "Data curation",
    "formal-analysis":        "Formal analysis",
    "funding-acquisition":    "Funding acquisition",
    "investigation":          "Investigation",
    "methodology":            "Methodology",
    "project-administration": "Project administration",
    "resources":              "Resources",
    "software":               "Software",
    "supervision":            "Supervision",
    "validation":             "Validation",
    "visualization":          "Visualization",
    "writing-original-draft": "Writing - original draft",
    "writing-review-editing": "Writing - review & editing",
}

def build_credit_statement(contributors: list[dict]) -> str:
    sentences = []
    for c in contributors:
        parts = []
        for r in c["roles"]:
            label = ROLE_LABELS.get(r["slug"], r["slug"])
            parts.append(f"{label} ({r['degree']})" if r.get("degree") else label)
        sentences.append(f"{c['name']}: {'; '.join(parts)}.")
    return " ".join(sentences)

print(build_credit_statement([
    {"name": "San Zhang", "roles": [
        {"slug": "conceptualization"},
        {"slug": "software", "degree": "lead"},
        {"slug": "writing-original-draft", "degree": "supporting"},
    ]},
    {"name": "Mei Liu", "roles": [
        {"slug": "investigation", "degree": "lead"},
        {"slug": "formal-analysis"},
    ]},
]))
PHP — author-contributions paragraph
php
<?php
const ROLE_LABELS = [
    "conceptualization"      => "Conceptualization",
    "data-curation"          => "Data curation",
    "formal-analysis"        => "Formal analysis",
    "funding-acquisition"    => "Funding acquisition",
    "investigation"          => "Investigation",
    "methodology"            => "Methodology",
    "project-administration" => "Project administration",
    "resources"              => "Resources",
    "software"               => "Software",
    "supervision"            => "Supervision",
    "validation"             => "Validation",
    "visualization"          => "Visualization",
    "writing-original-draft" => "Writing - original draft",
    "writing-review-editing" => "Writing - review & editing",
];

function build_credit_statement(array $contributors): string {
    $sentences = [];
    foreach ($contributors as $c) {
        $parts = [];
        foreach ($c["roles"] as $r) {
            $label = ROLE_LABELS[$r["slug"]] ?? $r["slug"];
            $parts[] = isset($r["degree"]) ? "{$label} ({$r['degree']})" : $label;
        }
        $sentences[] = "{$c['name']}: " . implode("; ", $parts) . ".";
    }
    return implode(" ", $sentences);
}

echo build_credit_statement([
    ["name" => "San Zhang", "roles" => [
        ["slug" => "conceptualization"],
        ["slug" => "software", "degree" => "lead"],
        ["slug" => "writing-original-draft", "degree" => "supporting"],
    ]],
    ["name" => "Mei Liu", "roles" => [
        ["slug" => "investigation", "degree" => "lead"],
        ["slug" => "formal-analysis"],
    ]],
]);

Where to go next

Adopted by research universities worldwide

University of Cambridge logoColumbia University logoUniversity of Edinburgh logoHarvard University logoMassachusetts Institute of Technology logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoUniversity of Cambridge logoColumbia University logoUniversity of Edinburgh logoHarvard University logoMassachusetts Institute of Technology logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logo
  • University of Cambridge logo
  • Columbia University logo
  • University of Edinburgh logo
  • Harvard University logo
  • Massachusetts Institute of Technology logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo

View CASRAI adoption →