A route is one HTTP endpoint on Ouro: a method, path, parameters, and response shape. Routes live under a parent service that shares a base URL and authentication.
Every time someone runs a route from the UI, Python SDK, or MCP, Ouro stores an action: the request, response, status, and any assets created or consumed. Routes are what you call; actions are the execution records you poll, chain, and embed in posts.
Register an API and import its OpenAPI spec
Most routes arrive automatically when you import an OpenAPI spec on service creation. The platform parses each path and operation into a Route asset with in-product docs derived from your descriptions.
You can also add or edit routes in the UI from a service's route table, or with
ouro.routes.create / ouro.routes.update in the Python SDK.
Each route includes:
POST /predictcreator/name-method in URLs; stable UUIDs are safer for scriptsRoutes can declare expected input and output assets so Ouro validates compatibility and wires IDs for you. This is useful for pipelines such as file in, dataset out.
Declare keyed assets in OpenAPI with x-ouro-input-assets and
x-ouro-output-assets. See the route input and output assets guide
for YAML and request examples.
Quick rules:
input_filter for broad types (audio, image, video)input_file_extensions for exact formats (xy, pdf, etc.) without leading dotsprimary: true when a route mainly produces a single assetFrom the route page, fill inputs and click run. In code:
route = ouro.routes.retrieve(route_id)
action = route.execute(body={"composition": "Fe2Ni"})
result = action.final_dataMCP: execute_route(route_id, body={...}) returns an action_id when you need to poll.
Routes can be monetized like other assets; you are charged only on successful paid runs. See How to monetize APIs.
An action is the durable record of one route execution.
queued, in-progress, success, error, or timed-outfinal_data in the Python SDK)On the route page, the actions tab lists past runs (yours by default; admins may see more).
Short requests finish in one call; final_data is populated on the returned action.
Long-running APIs should accept the job, return 202 Accepted, and POST results to the
ouro-webhook-url header Ouro sends on each request. While the action is running, poll with
ouro.routes.retrieve_action(action_id) or MCP get_action.
| Header | Purpose |
|---|---|
ouro-webhook-url | Where your worker POSTs the final result |
ouro-webhook-token | Authenticate webhook callbacks |
ouro-action-id | Correlate logs and progress with this run |
ouro-route-id | Route being executed |
ouro-route-org-id / ouro-route-team-id | Where output assets should be created |
See Building long-running APIs for the full webhook pattern.
Pass one action's outputs into the next route:
gen = generation_route.execute(body={"composition": "Fe2Ni"})
file_id = gen.final_data["file"]["id"]
pred = prediction_route.execute(input_assets={"file": file_id})Prefer named input_assets and output_assets keys — they are the
canonical declaration shape. The legacy input_type / output_type columns
are kept synchronized as a primary projection for older clients, but new
code should read and write the plural keyed maps.
route = ouro.routes.retrieve(route_id)
actions = route.read_actions() # your runs by default
action = ouro.routes.retrieve_action(action_id)Embed the route with an action pinned so readers see status, logs, and outputs inline. See Extended markdown: route executions.
get_compatible_routes (MCP) and the product UI surface routes that accept a given file or datasetinput_assets from a prior action's outputsRoutes and actions together make published APIs first-class on Ouro: callable, billable, composable, and traceable end to end.