Documentation

Trois façons de lire le contenu, et une référence générée à partir des routes elles-mêmes : elle ne peut donc pas décrire un point de terminaison qui n'existe pas.

Démarrages rapides

fetch, tout simplement

Pas de SDK, pas d'étape de compilation. Voilà toute l'intégration pour une liste de billets.

const response = await fetch(
  "https://api.schemahaus.com/v1/content/blog-post?locale=ka&limit=10",
  { headers: { authorization: `Bearer ${process.env.SCHEMAHAUS_TOKEN}` } },
);

const { data, meta } = await response.json();
// data is only what is PUBLISHED in Georgian. Nothing is substituted
// unless you ask: add &fallback=chain, and check item.localeFallback.

Next.js

Le SDK et un webhook de revalidation : quand un rédacteur clique sur Publier, la page est reconstruite sans attendre l'expiration d'un cache.

// app/[locale]/blog/[slug]/page.tsx
import { createClient } from "@schemahaus/client";

const cms = createClient({
  token: process.env.SCHEMAHAUS_TOKEN,
  site: process.env.SCHEMAHAUS_SITE,
});

export default async function Post({ params }) {
  const { locale, slug } = await params;
  const post = await cms.document("blog-post", slug, { locale });

  if (!post) notFound();
  return <article dangerouslySetInnerHTML={{ __html: post.data.body }} />;
}

// Publishing fires a webhook. Point a nextjs_revalidate webhook at your
// deploy and the page rebuilds itself when an editor presses publish.

Jekyll, à la compilation

Pour un site statique sans aucun environnement d'exécution : récupérez le contenu pendant la compilation et écrivez les fichiers attendus par le générateur.

# _plugins/schemahaus.rb — runs at build time, writes _posts/
require "net/http"
require "json"

site = ENV.fetch("SCHEMAHAUS_SITE")
token = ENV.fetch("SCHEMAHAUS_TOKEN")

uri = URI("https://api.schemahaus.com/v1/content/blog-post?locale=en")
request = Net::HTTP::Get.new(uri)
request["authorization"] = "Bearer #{token}"

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end

JSON.parse(response.body)["data"].each do |post|
  File.write("_posts/#{post["publishedAt"][0, 10]}-#{post["slug"]}.md",
             "---\ntitle: #{post["data"]["title"].inspect}\n---\n" +
             post["data"]["body"])
end

Référence de l'API

Lue dans l'arborescence des routes à la compilation. Un point de terminaison apparaît ici quand le fichier existe et disparaît quand il est supprimé : cette page ne peut donc pas documenter ce qui n'existe pas.

Diffusion

Le contenu publié, lu avec un jeton de diffusion. Vous pouvez le placer sans risque dans l'environnement d'un site consommateur : il peut lire, et rien d'autre.

  • GET/api/v1/authors

    The site's authors, with their per-language biographies.

  • GET/api/v1/content/{apiId}

    Published documents of one content type. Filter, sort, paginate by `page` or by cursor (`?cursor=` to start, then each page's `meta.nextCursor`); `?locale=` is strict unless `fallback` says otherwise.

  • GET/api/v1/content/{apiId}/{identifier}

    One published document, by slug or by document id.

  • GET/api/v1/media/{id}

    One media asset's metadata and variant URLs.

  • POST/api/v1/preview/verify

    Exchange a preview token for the draft it was minted for. Needs a delivery token with draft access.

  • GET/api/v1/site

    The site's settings and its content languages.

  • GET/api/v1/site/types

    The content types on the site, with their fields. Addressed by apiId; no internal ids are returned.

Gestion

Les écritures, liées à l'adhésion d'un membre : une clé ne peut jamais faire plus que la personne qui l'a créée. C'est ce qu'utilisent les scripts d'importation.

  • GETPOST/api/v1/manage/authors

    List or create authors.

  • PATCHDELETE/api/v1/manage/authors/{id}

    Edit or remove one author.

  • POST/api/v1/manage/documents

    Create a document in one language.

  • PATCHDELETE/api/v1/manage/documents/{id}

    Edit one language version, or soft-delete the whole document. Editing takes the revision you last read.

  • POST/api/v1/manage/documents/{id}/locales

    Start a translation of a document.

  • POST/api/v1/manage/documents/{id}/transition

    Move one language version through the workflow, including publishing it.

  • GET/api/v1/manage/documents/lookup

    Find a document by slug, drafts included — how an import decides whether it has already brought a post across.

  • POST/api/v1/manage/media

    Reserve an upload and get a presigned PUT for object storage.

  • POST/api/v1/manage/media/{id}/complete

    Confirm the bytes arrived. Idempotent, so a retried import does not count the storage twice.

  • GET/api/v1/manage/types

    Content types WITH their internal ids, which every write below needs.

Compatibilité Strapi

La forme des requêtes Strapi sur le même contenu publié, pour qu'un site existant puisse migrer avant d'être réécrit.

  • GET/api/strapi/api/{plural}

    The Strapi compatibility layer: Strapi's query shape over the same published content, so an existing site can move before it is rewritten.

Quatre règles à connaître avant de commencer

La diffusion est stricte par défaut
`?locale=ka` ne renvoie que ce qui est publié en géorgien. Un contenu manquant reste visiblement manquant au lieu de devenir silencieusement de l'anglais. Ajoutez `fallback=default` ou `fallback=chain` pour activer le repli, et vérifiez `localeFallback` sur chaque élément pour voir ce qui a été substitué.
L'API sert les données publiées, jamais les brouillons
Un document en cours de modification continue de servir sa dernière version publiée jusqu'à la prochaine publication. Si une modification n'apparaît pas, c'est qu'elle n'a pas été publiée : c'est voulu.
Les clés des médias ne changent jamais
Remplacer une image crée une nouvelle ressource avec une nouvelle URL. L'ancienne continue de fonctionner, car les caches périphériques et les sites déjà compilés pointent encore vers elle.
Chaque langue est publiée séparément
Publier l'anglais ne publie pas l'allemand. Un document n'a pas d'état de publication unique : chaque version linguistique a le sien.