> ## Documentation Index
> Fetch the complete documentation index at: https://developers.octaviatech.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Build with Octavia

> Which service to start with, and how to put together a real integration.

This page is a decision guide. It answers two questions: *which service do I activate
first*, and *how do I actually wire one up* so it survives contact with production.

***

## Start here

<Steps>
  <Step title="1. Pick the service that matches the problem">
    Building editorial content, a blog, or a multi-language site? Start with
    **AI CMS** — it is the service with a full reference today. Storing user uploads
    or generated media? **Storage**. Authenticating your own users? **Auth**.
    Taking money? **Payments**.

    <Card title="What is Octavia" icon="building" href="/platform/what-is-octavia" arrow="true">
      What each service covers.
    </Card>
  </Step>

  <Step title="2. Activate it and pick a plan">
    Enable the service from **Dashboard → Octavia Services**, then choose a plan. Every
    plan is the same API — the difference is what you are allowed to do before the API
    answers <code>426</code>.

    <Card title="Quickstart" icon="rocket" href="/quickstart" arrow="true">
      The click-by-click version, with screenshots.
    </Card>
  </Step>

  <Step title="3. Create a key at the lowest role that works">
    One key per system. Start with <strong>Read-only</strong> for anything that only
    reads, and raise the role only when a call actually fails with
    <code>403</code>.

    <Card title="Teams & API keys" icon="key-round" href="/platform/teams-and-keys" arrow="true">
      Roles, scopes, and rotation.
    </Card>
  </Step>

  <Step title="4. Use the SDK, not raw HTTP">
    Official clients exist for JavaScript, Python, PHP, C# and Go. They send the key
    for you, unwrap the envelope, and give you typed results.

    <Card title="All SDKs" icon="box" href="/api-reference/ai-cms/sdks/overview" arrow="true">
      Compare the five and pick one.
    </Card>
  </Step>
</Steps>

***

## Pick an SDK, not a language

The five SDKs wrap the same REST endpoints and return the same envelope. They differ
only in how the language spells things.

| **If your stack is**        | **Use**    | **Why**                                                                           |
| --------------------------- | ---------- | --------------------------------------------------------------------------------- |
| Node, Next.js, React        | JavaScript | TypeScript-first, covers the full surface, and is the one we build against first. |
| Django, FastAPI, scripts    | Python     | No third-party dependencies.                                                      |
| Laravel, WordPress, Symfony | PHP        | Uses cURL directly, so there is no PSR-18 client to wire up.                      |
| ASP.NET, Unity, Xamarin     | C#         | .NET 6+, returns `CMSResponse<T>` for every method.                               |
| Go microservices            | Go         | A single module, zero dependencies outside the standard library.                  |

<Note>
  Every SDK sends exactly one header, `x-api-key`, and none of them expose a way to
  add headers. If you find yourself wanting to set a header manually, the answer is in
  the gateway, not the client.
</Note>

***

## Put together something real

For AI CMS, the content model has an order. Building it in this order means each step
needs only what is above it.

```mermaid theme={null}
flowchart LR
    L["1 · Language"] --> A["2 · Author"]
    L --> C["2 · Category"]
    C --> SC["3 · Subcategory"]
    A --> ART["4 · Article"]
    C --> ART
    SC --> ART
```

<CardGroup cols={2}>
  <Card title="Content model" icon="file-text" href="/api-reference/ai-cms/content-management/introduction" arrow="true">
    Every resource, its fields, and what it depends on.
  </Card>

  <Card title="API quickstart" icon="rocket" href="/api-reference/ai-cms/quickstart" arrow="true">
    Build the whole model in about five minutes.
  </Card>
</CardGroup>

***

## Before you ship

Four things separate a working demo from an integration that holds up.

**Handle `429` and `426` differently.** `429` is transient — back off exponentially
with jitter. `426` means a plan quota is exhausted, and retrying cannot fix it. Putting
them in the same retry loop just burns rate-limit budget.

**Set a timeout.** The PHP SDK defaults to *no timeout*, so a hung request will hang
your worker. Set `timeoutMs` explicitly in every language.

<CardGroup cols={2}>
  <Card title="Rate limits & errors" icon="triangle-alert" href="/api-reference/ai-cms/rate-limits-and-errors" arrow="true">
    Which failures you can retry, and which you cannot.
  </Card>

  <Card title="Plans" icon="layers" href="/api-reference/ai-cms/plans" arrow="true">
    What each plan includes, limit by limit.
  </Card>
</CardGroup>

**Keep keys on the server.** A key in a browser bundle is a compromised key. Read it
from the environment, give each system its own, and rotate on a schedule.

**Paginate from the start.** `total` counts the filtered set, not the page. Build the
loop now rather than after the first timeout.

***

<CardGroup cols={2}>
  <Card title="Status codes" icon="list" href="/api-reference/ai-cms/status-codes" arrow="true">
    Every code and its meaning.
  </Card>

  <Card title="Support" icon="headset" href="https://support.octaviatech.app" arrow="true">
    Ask the engineering team.
  </Card>
</CardGroup>
