Public API & channels

Read exactly what the site needs.

Each site reads its own channel: the models and fields it needs, published content only, through a REST API that documents itself. Its key can only read, and only from your domains.

terminal

curl -H "x-api-key: $MOTEUR_KEY" \
  "https://api.moteur.io/projects/client-site/channels/public/article/entries?limit=10&sort=-publishedAt"

Setup

From project to site

Four steps, the first time. After that, the site just reads.

  1. Choose what the site sees

    New projects start with a site channel. Choose which models and pages it shows, which fields, which status and languages, how deep to follow links.

  2. Make a key

    A key that can only read, limited to that channel and to your site’s domains, with an expiry if you like. It’s all the site needs: the key knows its project and channel.

  3. Read

    Plain REST from any language, or the TypeScript client on a JavaScript site. The channel’s OpenAPI document says what comes back.

  4. Stay current

    A signed webhook tells your host when something is published, and preview tokens show drafts before they are.

Try it

Build a request, read the answer

These are real answers from the demo project’s public channel: published content only, in the channel’s fields. Choose the language, the order and how many, and watch the address and the answer change.

Build a request, read the answer
How many

GET…/projects/demo/channels/public/article/entries?locale=en&sort=-publishedAt&limit=2

The answer200 OK · X-Total-Count: 30

[
  {
    "id": "issue-01-1",
    "type": "article",
    "data": {
      "title": "We Started in a Garage in Montréal",
      "slug": "we-started-in-a-garage-in-montreal",
      "excerpt": "The winter of 1968 in Montreal was particularly brutal. The streets of Le Plateau were deserted, the snow knee-deep, and in a garage on Rue Saint-Denis, three men were building something nobody had asked…",
      "author": "henri",
      "readingTime": 2
    }
  },
  {
    "id": "issue-02-1",
    "type": "article",
    "data": {
      "title": "Six Months with the MAISON-3: A Personal Journal",
      "slug": "six-months-with-the-maison-3-a-personal-journal",
      "excerpt": "His name is Trois — the name my daughter gave him on the first evening, pointing to the number on his shoulder. I told her machines do not need names. She looked at me as though I had said something very…",
      "author": "marguerite",
      "readingTime": 11
    }
  }
]

Recorded from the Moteur Journal, the demo project. Each entry trimmed to five of its fields. Without a language, every field comes back in all of them.

Beyond entries

What a channel serves

Everything a site needs to draw its pages, through the same key.

  • Entries

    Entries and pages

    Articles, events, products, and the site’s pages built from blocks.

    • One page by its slug
    • Blocks in the order they’re placed
  • Navigation

    Menus, sitemap, breadcrumbs

    The site’s menus and page tree, so the frontend never hard-codes a link.

    • A sitemap ready for search engines
    • Breadcrumbs for any page
  • Images

    Images at the size you ask

    Every picture resized on request, in WebP or AVIF, around its focal point.

    • Cached for a year
    • Alt text in every language

    your frontend

    <img {...imageAttributes(article.data.cover, {
      ratio: '16:9', format: 'avif',
      sizes: '50vw', locale: 'fr',
    })} />
  • Forms

    Forms, both ways

    A channel describes a form. The site posts what visitors send, and it lands in the Studio’s Inbox.

    • A spam trap built in
    • Email or webhook on each one
  • Types

    An OpenAPI document per channel

    Each channel describes itself, so you can read it, test it, or generate types from it.

    • Download it from the Studio
    • Always the current models
  • Client

    A TypeScript client

    For JavaScript sites: channels, images, block components and previews, in one small library.

    • Block types to your components
    • Preview sessions for drafts

    your frontend

    import { createMoteurPublicClient } from '@moteurio/client';
    
    const moteur = createMoteurPublicClient({
      baseURL: 'https://api.moteur.io',
      auth: { type: 'apiKey', apiKey: process.env.MOTEUR_KEY, projectId: 'client-site' },
    });
    
    // The ten newest articles the channel shows: published, in its fields.
    const latest = await moteur
      .channel('public')
      .entries.list('article', { limit: 10, sort: '-publishedAt' });

Keys

A key that can only read

A site’s key reads its channel and nothing else. It can’t write, can’t see drafts, and can’t be used from someone else’s domain in a browser.

  • Stored hashed: the key is shown once, when it’s made
  • Limited to channels and to your domains, with an expiry and rotation
  • Up to 20 per project, so each site has its own and can lose it alone
  • Sent in a header, never in the address

your frontend

import { createMoteurPublicClient } from '@moteurio/client';

const moteur = createMoteurPublicClient({
  baseURL: 'https://api.moteur.io',
  auth: { type: 'apiKey', apiKey: process.env.MOTEUR_KEY, projectId: 'client-site' },
});

// The ten newest articles the channel shows: published, in its fields.
const latest = await moteur
  .channel('public')
  .entries.list('article', { limit: 10, sort: '-publishedAt' });

Questions about the API

A developer asksIs there a GraphQL API?

MoteurNot today. Each channel is a REST API that already sends only the fields the site asked for, with linked entries in the same answer, and an OpenAPI document that describes it.

A tech lead asksWhat are the limits?

MoteurA thousand requests every fifteen minutes per project, and a monthly number set by the project’s plan. Past the month’s requests, the public API pauses until the month turns over, or until you add a pack of 50,000.

A developer asksCan we call it from the browser?

MoteurYes, with a key limited to your site’s domains. That limit is checked by the browser, so keep anything private on a server.

A developer asksHow does the site know something changed?

MoteurA webhook, signed so your server knows it’s us, retried for two hours if your server is down. Point it at your host’s rebuild hook.

A developer asksCan the site show drafts?

MoteurYes, through a preview token that lasts half an hour and can be limited to one entry. The Studio’s preview opens your site with one.

Read your first entry.

Start a project for free, make a key for its site channel, and read it from your site.