Allt det gör, på en sida.

Verifierat i koden som kör det, den 2 september 2026. Inget här är planerat eller på väg.

Adminen finns på engelska och italienska, så de här bilderna är den engelska uppsättningen.

Schemat är formuläret.

Det du skriver till vänster är det redaktörerna får till höger.

  • fields.text()
  • fields.textarea()
  • fields.richText()
  • fields.number()
  • fields.boolean()
  • fields.datetime()
  • fields.slug()
  • fields.select()
  • fields.relation()
  • fields.media()
  • fields.group()
  • fields.array()
  • fields.json()
  • fields.blocks()
Flaggor, inte skärmar
required och localized är två booleaner på fältet.
Slug från titeln
fields.slug({ from: 'title' }) fyller i sig själv; select bär fasta alternativ.
Även från adminen
Egna collections kan skapas i adminen och sparas i databasen.

Ett innehåll, fyra sätt att läsa det.

Välj det din stack redan talar.

Publika poster kräver ingen nyckel. Back-office-dokument kräver en API-nyckel eller en bearer-token.

shellHTTP
curl 'https://cms.altovar.net/api/v1/collections/blog-post/entries?locale=en'

{ "data": [ { "id": "fdoc_16d9i3ef", "locale": "en",
              "data": { "title": "EU-first content infrastructure", … },
              "seo":  { "metaTitle": …, "metaDescription": …, "robots": "index,follow" } } ],
  "pagination": { "page": 1, "limit": 20, "total": 3, "totalPages": 1 } }

# The back-office route is the same shape, with a key:
curl -H 'x-api-key: sk_…' \
     'https://cms.altovar.net/api/v1/collections/blog-post/documents?limit=10'

En typad klient med samma kuvert: data och pagination.

blog.tsTS
import { OspreyClient } from '@osprey/client'

const osprey = new OspreyClient({
  baseUrl:  'https://cms.altovar.net',
  tenantId: 'altovar',
})

const { data, pagination } = await osprey
  .collection('blog-post')
  .listEntries({ locale: 'en', limit: 10 })

Bara queries, över POST. GraphiQL finns i utvecklingsläge.

graphqlGQL
POST /api/v1/graphql
x-api-key: sk_…

query Posts($limit: Int) {
  documents(collectionSlug: "blog-post", status: "published", limit: $limit) {
    data { id status data }
    pagination { total }
  }
}

Poster hamnar i Astro content collections vid bygget. Ingen nyckel på edgen.

src/pages/index.astroASTRO
---
import { getCollection } from 'astro:content'

const posts = (await getCollection('blog'))
  .filter((p) => p.data.locale === 'en')
  .sort((a, b) => b.data.publishedAt.localeCompare(a.data.publishedAt))
---
{posts.map((p) => (
  <article>
    <a href={'/' + p.data.slug}>{p.data.title}</a>
    <p>{p.data.excerpt}</p>
  </article>
))}
Läs OpenAPI-dokumentet →

Publicera här, dyk upp där.

Utkast förblir privata. En publicerad post når den publika endpointen inom en minut, och en webhook kan bygga om webbplatsen.

Tre statusar
draft, published, archived. Sidor lägger till granskning, godkännande och schemaläggning.
Signerad webhook
HMAC-SHA256 över kroppen i x-osprey-signature. Nio händelser, hemligheten krypterad i vila.
Cache-headers
Publika läsningar bär max-age=60 med stale-while-revalidate, redo för vilken cache som helst framför.

Tio språk, en matris.

Varje lokaliserat fält, varje språk, räknat.

Innehållsspråk
en, it, es, de, fr, nl, pl, sv, pt, ro, satta per arbetsyta.
Admin
Engelska och italienska, växlas från det övre fältet.
Täckning
En matris per sida och språk, och de saknade strängarna som CSV.
Leverans
En frågeparameter väljer språk; hreflang-alternativ följer med varje post.

Din domän, i fyra steg.

Via API:et i dag. Inställningssidan är på väg, och den här sidan säger det.

  1. Gör anspråk POST:a hosten till domän-endpointen. Den väntar som pågående.
  2. Bevisa Lägg till TXT-posten _osprey-verify.<host> med token du fick tillbaka.
  3. Verifiera POST:a igen med verify: true. Hosten flyttas till arbetsytan.
  4. Peka CNAME till plattformen. Certifikatet utfärdas vid första anropet.
domainsHTTP
POST /api/v1/admin/domains
Authorization: Bearer <jwt>
{ "host": "www.example.com" }

{ "status": "pending",
  "verification": { "type": "TXT",
                    "name": "_osprey-verify.www.example.com",
                    "value": "osprey-verify=…" } }

Egna domäner beror på planen eller på hosting-tillägget.

Kontroll som visar sitt arbete.

Varje rad nedan är en route och en skärm, inte en roadmap.

Roller
admin, editor, author, contributor, viewer
API-nycklar
hashade, visade en gång, skrivskyddsflagga, utgång
Revisionslogg
vem, vad, när och varifrån, för varje tillståndsändring
Versioner
sidhistorik med diff och återställning
Papperskorg
raderade sidor väntar; du återställer dem eller raderar dem för gott
Tillsammans
närvaro och delad sidredigering, fält för fält
Samtycke
cookie-banner och en samtyckeslogg med hashad IP
Radering och export
ett anrop maskerar en registrerad; export från adminen eller CLI:t
Inloggning
OpenID Connect per arbetsyta, eller ett lokalt lösenord
Hastighetsgränser
en hink per routefamilj, gränser i svarshuvudena

Delarna runt omkring.

Två publicerade paket, ett CLI, en MCP-server och en self-host-stack.

@osprey/client
typad SDK, React-blockrenderare, samtyckeshanterare
@osprey/astro
innehållsloader, SEO-head, översättningssynk
CLI
setup, init, dev, build, generate-types, link, export
MCP-server
sexton verktyg över stdio, för AI-agenten du redan använder
Self-host
en compose-fil och en guide vid första start på /setup
AI-assistent
översätter luckor, fyller i SEO, skriver alt-texter; av tills du slår på den

Ditt innehåll. Din server. I dag.

Gratisplan, inget kort. Driftat i EU, eller på dina egna maskiner.