Importing an OpenAPI document
Riviera reads your OpenAPI document, shows which operations can become tools and why the others can't, and adds the ones you choose to a draft. This page lists exactly what it accepts.
Before you start
You need a Riviera project and an OpenAPI document that describes your API.
- Format. OpenAPI 3.0.0 to 3.0.4 or 3.1.0 to 3.1.2, as JSON or YAML (YAML 1.2, one document). Swagger 2.0 and OpenAPI 3.2 are not supported. Riviera refuses a few YAML features whose meaning differs between YAML versions: merge keys (
<<), tags other than the core ones, directives such as%YAML 1.1, numbers written with a leading zero or in hexadecimal or octal, infinity and NaN, and more than one document in a file. The error names the line. - Size. Up to 1 MiB, no more than 200 operations, nested no deeper than 40 levels and no more than 50,000 nodes. The limits apply to the document after YAML aliases are expanded, so an alias counts as much as the text it stands for. A larger document has to be split. Removing whitespace is enough for a document that is only over the byte limit because of its formatting.
- A public server address. Riviera calls your API from its own servers, so the server URL in the document must be an absolute, public HTTPS address, such as
https://api.example.com/v1. A relative address like/api/v3is not enough. - How to provide it. Give a direct public URL to the JSON or YAML, or upload or paste it. A
.json,.yamlor.ymlfile is accepted. A URL can’t carry credentials, a query string or a fragment, can’t redirect, and must answer within ten seconds. Upload a document that is private.
The import workflow
- In your project, open Build and choose Import an API.
- Add a source: a public document URL, or a JSON or YAML file or pasted text. Give it a label. A project can have up to ten API sources.
- Choose Analyze API. Riviera reads the document. It never calls your API while analyzing. The result lists the operations found, which can become tools, and which can’t, grouped by reason.
- Choose the tools to add. Operations that only read (GET) are selected for you. Operations that change data (POST, PUT, PATCH and DELETE) are not: you add each one on purpose.
- Set up authentication where an operation needs a credential. Riviera asks only for what the document declares. See authentication.
- Choose Add tools to Draft (the button shows how many). Each selected operation is reviewed separately and added to Draft as a tool. If one fails, Riviera tells you why and still adds the others. Nothing reaches agents yet.
- Edit and publish. See below.
How an operation becomes a tool
- Name
- The
operationIdin snake case:createInvoicebecomescreate_invoice. Without one, the name is built from the method and the fixed parts of the path:GET /invoicesbecomeslist_invoices,GET /invoices/{id}becomesget_invoicesandPOST /invoicesbecomescreate_invoices. When two operations get the same name, the second takes its method as a suffix, then a number. Names are at most 64 characters, and two enabled tools can’t share a name when you publish. - Description
- The operation’s
description, or itssummarywhen there is no description, or the method and path when there is neither. This is what agents read to choose the tool, so it is usually the first thing to edit. - Input
- One input schema. Each parameter becomes an argument named after where it lives and what it is called:
path_invoice_id,query_limit,header_x_request_id. A JSON request body becomes one argument,body. Required parameters stay required. - Output
- The JSON object schema of the success response, which agents see as the tool’s output schema.
- The call
- Riviera puts the arguments back where your document says they go, sends the request to the server URL and path with the credential you saved, and returns your API’s JSON response.
- Status
- An operation is either ready to add, or needs a decision first (a write, a deprecated operation, a credential to set up, a choice of authentication), or can’t become a tool.
A worked example shows an operation and the tool it produces, from Riviera’s own importer.
What is supported
Riviera only creates a tool when it can call the operation exactly as your document describes it. It does not guess. An operation that falls outside these rules is reported, with the reason, and the rest of the document still imports.
| Area | Supported | Not supported |
|---|---|---|
| Server | One absolute public HTTPS server URL for the operation. Server variables that have a default value, which must be a plain host name or path segment. | Several alternative servers, relative URLs, a variable without a default, a URL with credentials, a query or a fragment, private addresses. |
| Operations | GET, POST, PUT, PATCH and DELETE that answer in one response. | HEAD, OPTIONS and TRACE. Callbacks, response links and streaming. Two templated paths with the same shape, such as /a/{x} and /a/{y}. |
| Parameters | Required path parameters. Query and header parameters with a simple value. Query arrays of simple values sent as repeated fields (explode). | Cookie parameters. Object-valued parameters. Any other serialization style, and content, allowReserved or allowEmptyValue. A header that carries a credential or routing, such as Authorization or Host: declare the credential as a security scheme instead. |
| Request body | A required body whose only media type is application/json, on POST, PUT, PATCH or DELETE. | A body without required: true (OpenAPI treats a missing flag as optional). A body on GET. Multipart, form, XML, binary, or a JSON body that also offers another media type. |
| Responses | Every success status (2xx) described with the same application/json schema, whose root is an object. Or 204 with no body, for every success status. | A success response with no schema. Different schemas for different success statuses. A list or a single value at the top level of the response. Wildcard statuses such as 2XX. Anything but application/json. |
| Schemas | An explicit type on every schema (object, array, string, number, integer or boolean). properties, required, items, additionalProperties as a boolean or a schema, enum, minimum and maximum (and their exclusive forms), lengths, pattern, minItems and maxItems, uniqueItems, multipleOf, minProperties and maxProperties. format, for the formats the schema compiler knows, such as date-time, date, email, uri, uuid, hostname, ipv4, ipv6, int32, int64, float and double: these are checked when an agent calls the tool. Any other format (uint64, int16 or a name of your own) is ignored and the operation still converts. pattern, checked with a regular-expression engine that runs in time proportional to the input. const in OpenAPI 3.1. Vendor extensions (x- fields) in a schema are ignored. On an operation, x-async-job and x-streaming mark a workflow Riviera does not run. title, description. example, default and deprecated are read and left out. | nullable: true and type arrays such as ["string", "null"]. oneOf, anyOf, allOf, not and discriminator. Recursive schemas. readOnly and writeOnly. x-nullable, which changes what a value may be. xml and externalDocs inside a schema. Boolean schemas. Binary and byte strings. A pattern that uses lookahead, lookbehind or a backreference, a repeat count above 1,000, or that is very large. A schema over 5,000 values, or more than 40,000 values in distinct schemas in one import. Any keyword not on the supported list. |
| References | A $ref that points inside the same document, such as #/components/schemas/Invoice, with no other field beside it. Riviera follows only what a tool uses: parameters, the request body and success responses. A broken reference in an error response, an example, a header or a link does not stop an operation. | References to other files or URLs. A field next to a $ref. A reference cycle. References nested more than 40 levels, or a document whose references expand past 2 MiB of text or 250,000 values in total: the budget is shared by the whole document, so operations analyzed after it is spent are excluded. |
| Authentication | None, an API key in a header, an HTTP bearer token, OAuth client credentials, and per-user OAuth through your own authorization server. One requirement per operation. | HTTP Basic. API keys in a query string or cookie. Several alternative requirements. Requirements that combine schemes. Password and implicit OAuth flows. See authentication. |
Why an operation is excluded
The import result groups excluded operations by cause, and each operation in a group keeps its own detail. Riviera reports the first cause that blocks an operation. Fixing it can reveal another, so import again after each round of changes.
| Reason shown | Codes | What to change in your document |
|---|---|---|
| The server address can't be used | SERVER_REQUIRED SERVER_UNSAFE SERVER_VARIABLES SERVER_PATH | Declare one absolute HTTPS server URL. Give every server variable a default value. Remove alternatives, or keep the one that agents should use. |
| The server isn't a public HTTPS address | ORIGIN_* | Tools can only call servers that are reachable on the public internet over HTTPS. |
| Asks the agent for a credential header | HEADER_RESERVED | Declare the credential as a security scheme, not as a header parameter, so Riviera supplies it. |
| Authentication Riviera can't supply yet | SECURITY_UNSUPPORTED SECURITY_ALTERNATIVES SECURITY_COMBINED SECURITY_SCOPES SECURITY_OAUTH SECURITY_HEADER SECURITY_INVALID | Use one HTTP bearer, header API key or OAuth requirement for each operation. |
| Sends or returns files, forms or streams | MEDIA_UNSUPPORTED ENCODING_UNSUPPORTED SCHEMA_BINARY | Only JSON request and response bodies can become tools. |
| Returns a list or a single value, not an object | RESPONSE_ROOT | Tools return JSON objects. Wrap the list in an object, for example { "items": [...] }. |
| The success response isn't described | RESPONSE_REQUIRED RESPONSE_204 RESPONSE_VARIANTS RESPONSE_LINKS | Declare a JSON schema for each 2xx response, or a 204 with no body, and use the same schema for every success status. |
| Uses schema features Riviera can't map yet | SCHEMA_UNSUPPORTED SCHEMA_TYPE SCHEMA_ITEMS SCHEMA_REQUIRED SCHEMA_BOUND SCHEMA_INCOMPATIBLE INVALID_STRUCTURE REF_* | Remove nullable, x-nullable, unions, composition keywords and unknown keywords from the schemas the operation uses. Declare a type and items explicitly. Put fields in the referenced definition instead of beside the $ref. Replace recursive schemas with a bounded definition. |
| Uses a pattern Riviera can't check safely | SCHEMA_PATTERN | Remove lookahead, lookbehind and backreferences from the pattern, keep repeat counts at 1,000 or below and the pattern small, or remove the pattern. |
| Too much schema to check in one import | SCHEMA_TOO_LARGE IMPORT_BUDGET | One operation's schema is over 5,000 values, or the import has more than 40,000 values in distinct schemas. Split the document, or remove the operations and fields an agent does not need. |
| Uses parameters Riviera can't map | PARAMETER_* PATH_REQUIRED ARGUMENT_COLLISION BODY_OPTIONAL CONTRACT_INCOMPATIBLE MAPPING | Use path, query and header parameters with simple values. Mark a request body required: true. Rename parameters that collapse to the same argument name. |
| The contract can't be mapped to a tool | TEXT_LIMIT | An operation name or description is longer than the supported length. Shorten it and analyze again. |
| Its path clashes with another path | PATH_AMBIGUOUS | Two templated paths have the same shape, so a call could reach either. Make one of them distinct. |
| Uses a method or workflow Riviera can't run | METHOD_UNSUPPORTED WORKFLOW_UNSUPPORTED | Use GET, POST, PUT, PATCH or DELETE, without callbacks, streaming or asynchronous job orchestration. |
Documents refused whole
Some problems are about the document, not one operation. Riviera refuses the whole document and says why. Nothing is partly imported. A webhooks section is not one of them: it is left out and counted in the result, and the rest of the document imports.
| Code | Cause | What to do |
|---|---|---|
INVALID_JSON | The text starts with { or [ and is not valid JSON. | Fix the syntax: commas, quotes and brackets. |
INVALID_YAML | The text is not valid YAML. The message names the line where it was found. | Fix the syntax: indentation, quoting and brackets. |
YAML_UNSUPPORTED | Valid YAML that uses something Riviera does not read: merge keys, custom tags, directives, leading-zero, hexadecimal or octal numbers, infinity or NaN, or more than one document. | Write the values out in plain YAML, as the message says. |
VERSION_UNSUPPORTED | Not OpenAPI 3.0.0 to 3.0.4 or 3.1.0 to 3.1.2. | Use a supported version. |
DOCUMENT_LIMIT | Over 1 MiB, nested too deeply, or too many nodes. | Reduce the document or split it. |
OPERATION_LIMIT | More than 200 operations. | Split the document into parts of at most 200 operations. |
ORIGIN_LIMIT | More than ten different API addresses in one source. | Split the document into sources with at most ten. |
REPORT_LIMIT | The tool definitions generated from the document would be larger than 2 MiB. | Split the document. |
SOURCE_URL SOURCE_FETCH DOCUMENT_TIMEOUT EMPTY_DOCUMENT | Riviera couldn't read a document: the URL isn't absolute or carries credentials, a query or a fragment, the fetch failed, redirected or took more than ten seconds, or nothing was supplied. | Use a direct public URL, or upload the JSON. |
WEBHOOKS_ONLY | The document has a webhooks section and no paths. Webhooks are requests your API sends, not operations an agent can call. | Import a document that describes the operations agents should call. |
DIALECT_UNSUPPORTED | The document sets jsonSchemaDialect. | Remove it and use the supported schema keywords. |
PATH_REF | A path item is defined by $ref. | Write the path item in place. |
DUPLICATE_KEY | The same key appears twice in one object, in JSON or in YAML. | Remove the duplicate. |
INVALID_STRUCTURE | The document is not an OpenAPI object, or info.title or info.version is missing. | Correct the structure. |
The fixes that matter most
These are the changes that unlock the most operations in documents we have looked at. They are patterns, not a measured rate: see the guide for what we measured and how small that sample is.
- Declare one absolute HTTPS server URL.
- Set
required: trueon request bodies that are required. In OpenAPI, a body with no flag is optional. - Declare each credential as a security scheme, with one requirement per operation.
- Describe one JSON success response per operation, with an object at its root.
- Remove
nullable, unions and composition keywords from the schemas that operations use.
Editing and publishing
An imported tool is a first draft. Your summaries were written for people reading documentation, and agents choose a tool from its name and description alone. In Build, edit a tool’s name, its description and the description of each parameter, and turn tools on or off. Your document and your API are not touched.
Choose Review and publish to see what would change, tool by tool, against Production. Publishing creates a new version and makes it what agents read. It needs no deploy of your API. If the draft is invalid, publishing is refused with the reason and Production stays as it was.
To check your edits before publishing, write the requests customers make and the tool that should handle each, and run a model test on the draft. See the overview for what a test does and doesn’t check.
When your API changes
Analyze the updated document again. Riviera lists the operations that were added, changed and removed, and nothing changes until you review it. Your edited names, descriptions and settings are kept, while the input and output schemas and the request mapping come from the new document. A removed operation can only be turned off in Draft. Agents keep reading the published version until you publish again.
What Riviera keeps
Riviera does not keep your raw document. It keeps the tool definitions it produced, the security information it needs, the reasons for exclusions and where the document came from. It does not keep the example and default values in your schemas, and never keeps credentials in plain text. Names, descriptions and schema constraints are product content and are visible to members of your project.