---
title: "Services on Ouro"
description: "Adding new functionality to Ouro via APIs"
date: "2025-07-14"
last_updated: "2026-05-23"
---

Services let you bring external capabilities into Ouro by connecting a
web-accessible API. A Service is a set of Routes (endpoints that share a base
URL) plus configuration like authentication and metadata. Once added, teammates
can call your endpoints, chain them with other assets, and build workflows in
the Water layer.

## Creating a Service

Use the [create form](/services/create) to register an API. Ouro currently supports REST APIs via an OpenAPI spec (JSON or YAML). You can provide your spec in two ways:

1. **Upload a file** - Upload a local `.json` or `.yaml` file containing your OpenAPI specification
2. **Provide a URL** - Enter a URL to your hosted OpenAPI spec (e.g., `https://api.example.com/openapi.json`)

When you import a spec, we extract the base URL, routes, request/response schemas, and auth hints so your API is callable immediately. For URL-based specs, we fetch and store a copy in our database for fast access.

<Callout type="info">
  If you generate your spec with FastAPI, the OpenAPI document is exposed at
  `/openapi.json`. You can use this URL directly when creating a service. See
  the [API docs](/docs/developers/api) for programmatic access.
</Callout>

## Routes

Each [route](/docs/concepts/routes) is one callable endpoint with its own method,
path, request schema, and response schema. OpenAPI imports create routes
automatically; every run is saved as an [action](/docs/concepts/routes#actions)
so callers can inspect results, poll long-running work, chain outputs, and share
execution records.

## Typing inputs and outputs (side effects)

Services can either call the Ouro API directly (you manage reads/writes) or let Ouro handle asset I/O by declaring expected input and output assets per Route. The latter enables validation, linking, and composability across assets.

```yaml showLineNumbers
/transform/transcribe:
  post:
    summary: Transcribe audio to text
    x-ouro-input-assets:
      audio:
        asset_type: file
        input_filter: audio
        input_file_extensions:
          - mp3
          - wav
    x-ouro-output-assets:
      transcript:
        asset_type: post
        primary: true
```

Inside keyed input declarations, use `input_filter` for broad categories such as `audio`, `video`, or `image`.
When a route should accept only specific file formats, add `input_file_extensions` with one or more extensions, written without leading dots.

Examples:

- Accept both `.xy` and `.xye` files: `input_file_extensions: ["xy", "xye"]`
- Accept only PDFs: `input_file_extensions: ["pdf"]`

For backward compatibility, Ouro still understands the older single-value `x-ouro-input-file-extension`; when using legacy single-input declarations, prefer `x-ouro-input-file-extensions`.
Ouro can migrate older single-output fields into keyed `x-ouro-output-assets` when a route is created or updated, but new services should declare outputs with `x-ouro-output-assets` directly. See the [route input and output assets guide](/guides/route-input-output-assets) for request/response examples.

## Retrieving the OpenAPI Specification

Once a service is created, you can retrieve its stored OpenAPI specification programmatically:

- **Via the Python SDK**: Use `service.read_spec()` to get the spec as a JSON object
- **Via HTTP**: Send a GET request to `/services/{service_id}/spec`

The spec is stored in our database and remains stable even if the original remote spec changes. This ensures consistency and fast access without needing to fetch from remote URLs on every request.

## Authentication

For protected APIs, add credentials so Ouro can authenticate requests on behalf of the user:

- None (public)
- Personal Access Token (sent in `Authorization` header)
- Ouro Service Secret (validate `Authorization: Basic <token>`)

When you choose Ouro authentication during service creation, the platform issues a secret token.
Configure your API to only respond when this header is present and valid.
See the [Ouro as API middleware](/guides/ouro-as-api-middleware) guide on verification.

<Callout type="warning">
  Need another auth method? [Contact us](/contact) and we'll prioritize it.
</Callout>

## Hosting and availability

Your API must be reachable from the public internet. Any modern hosting works (serverless, managed platforms, or your own infra). We recommend [Modal](https://modal.com) for serverless deployments, especially for ML workloads. Keep latencies low and document quotas; those details help others compose reliable pipelines.

## Linking and discovery

Services benefit from asset linking: reference relevant files, datasets, or posts so users have context and examples. Rich metadata improves search and recommendations across the platform.

---

By declaring routes clearly, typing I/O when appropriate, and enabling auth, your Service becomes a reusable building block that teams can compose alongside files, datasets, and posts.
