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

# Build APIs from a Spec

> Hand Revolte an OpenAPI spec and have it implement the endpoints against your existing backend patterns — routes, validation, and tests included.

This walkthrough points Revolte at a real OpenAPI spec and shows what comes back: routes wired into your existing structure, validation that mirrors the spec, and a test suite that already passes.

***

<div class="dotted-steps">
  <Steps>
    <Step title="Understand the existing setup (optional)" icon="terminal">
      Kick off the session by asking Revolte to map the codebase's conventions before it writes anything. Read the summary it comes back with — it's what decides where the new endpoint should live.

      ```text theme={"dark"}
      Explore the codebase and explain how APIs are currently implemented.

      Focus on:
      - Existing routing and API structure.
      - Authentication and authorization flow.
      - Service and database layer patterns.
      - Validation and error handling approach.
      - Existing tests and testing conventions.

      Summarize your findings and suggest where this new API should live.
      ```
    </Step>

    <Step title="Implement APIs from your spec" icon="terminal">
      With the conventions settled, point Revolte to the OpenAPI spec and name the endpoints you want built. It reads the file directly for paths, request and response schemas, and expected behavior — you shouldn't need to restate any of that in the prompt.

      ```text theme={"dark"}
      Implement the two endpoints defined in spec/openapi.yaml:
      - POST /api/v1/invoices
      - GET /api/v1/invoices/{id}

      Requirements:
      - Follow the existing project architecture and conventions.
      - Reuse existing services, utilities, and middleware where possible.
      - Validation and status codes should match the spec exactly.
      - Follow the existing authentication and authorization pattern.

      Tests:
      - Write tests covering both endpoints, including the error cases.
      - Run the full suite and fix any failures before finishing.
      ```
    </Step>

    <Step title="Matches your existing patterns">
      Revolte works through the implementation and makes the changes. If you're in the chat view, click **View changes** to open the diff on the right and follow along:

      ```typescript theme={"dark"}
      // routes/invoices.ts
      router.post(
        "/api/v1/invoices",
        requireAuth,
        validateBody(createInvoiceSchema),
        invoicesController.create
      );

      router.get(
        "/api/v1/invoices/:id",
        requireAuth,
        invoicesController.getById
      );
      ```

      ```typescript theme={"dark"}
      // schemas/invoice.schema.ts
      export const createInvoiceSchema = z.object({
        customerId: z.string().uuid(),
        lineItems: z.array(
          z.object({
            description: z.string(),
            quantity: z.number().int().min(1),
            unitPriceCents: z.number().int().min(0),
          })
        ).min(1),
        dueDate: z.string().date().optional(),
      });
      ```
    </Step>

    <Step title="Tests pass before you look at it">
      Before you dig into the diff itself, check the test output further up in the session — Revolte runs the suite it just wrote as part of the same run, so a failure shows up here first instead of surprising you in review.

      ```text theme={"dark"}
      PASS  test/invoices.test.ts
        POST /api/v1/invoices
          ✓ creates an invoice for a valid payload (38ms)
          ✓ rejects a payload missing lineItems (11ms)
          ✓ returns 422 when the customer has no payment method (9ms)
        GET /api/v1/invoices/:id
          ✓ returns the invoice when it exists (7ms)
          ✓ returns 404 for an unknown id (6ms)

      Tests: 5 passed, 5 total
      ```
    </Step>

    <Step title="Continue iterating">
      Once the diff and tests both check out, stay in the same session rather than opening a new one — it already has the spec and the codebase's conventions loaded, so a follow-up prompt like either of these stays scoped instead of starting over:

      ```text theme={"dark"}
      Add pagination and filtering to GET /api/v1/invoices.

      Requirements:
      - Support page and limit query params.
      - Allow filtering by status (draft, sent, paid, overdue).
      - Follow the existing response format.
      ```

      ```text theme={"dark"}
      Add a PATCH /api/v1/invoices/:id endpoint to update line items
      on a draft invoice, with tests covering the case where the
      invoice has already been sent.
      ```
    </Step>
  </Steps>
</div>

***

## Related

* [Fix a Production Bug](/use-cases/fix-a-bug)
* [Generate Tests](/use-cases/generate-tests)
* [YAML Configurations](/yaml/overview)
