# OpenAPI Tesla does not parse OpenAPI documents or generate client modules. It provides request values and middleware that generated or hand-written clients can use to represent OpenAPI parameter serialization. ## Parameter locations OpenAPI parameter location decides which part of the HTTP request carries a value. Tesla keeps that boundary in generated or hand-written client code: `in` chooses the Tesla API, while `style`, `explode`, and `allowReserved` become serialization options where they apply. | OpenAPI location | Tesla API | | --- | --- | | `path` | `Tesla.OpenAPI.PathTemplate`, `Tesla.OpenAPI.PathParam`, `Tesla.OpenAPI.PathParams`, and `Tesla.Middleware.PathParams` in `:modern` mode | | `query` | `Tesla.OpenAPI.QueryParam`, `Tesla.OpenAPI.QueryParams`, and `Tesla.Middleware.Query` in `:modern` mode | | `querystring` | `Tesla.OpenAPI.QueryString` passed directly as the request `:query` | | `header` | `Tesla.OpenAPI.HeaderParam` and `Tesla.OpenAPI.HeaderParams.to_headers/2` | | `cookie` | `Tesla.OpenAPI.CookieParam` and `Tesla.OpenAPI.CookieParams.to_headers/2` | `path` and `query` parameters use middleware because they are transformed into the final request URL. `header` and `cookie` parameter collections produce raw header tuples before the request enters the middleware stack. In `Tesla.Middleware.Query` `:modern` mode, values matching `Tesla.OpenAPI.QueryParams` definitions use OpenAPI query serialization. Other query params remain normal Tesla query params. OpenAPI does not define a global operation flag for rejecting unknown query parameter names. When a query parameter schema uses `additionalProperties`, keep that as an object-valued `Tesla.OpenAPI.QueryParam` value. If a generated client needs a closed set of top-level query names, validate that in the generated operation module before calling Tesla. `querystring` is separate from `query` because OpenAPI treats it as the entire query string value. It must not be mixed with normal query parameters. ## Query string operations OpenAPI `in: "querystring"` treats the entire query string as one value. Use `Tesla.OpenAPI.QueryString` for those operations instead of `Tesla.OpenAPI.QueryParam`: ```elixir defmodule MyApi.Operation.Search do alias MyApi.Client alias Tesla.OpenAPI.QueryString defstruct query_string: nil def handle_operation(%Client{} = client, %__MODULE__{} = operation, opts) do request_opts = [ method: :get, url: "/search", query: QueryString.form!(operation.query_string), opts: opts ] Tesla.request(client.client, request_opts) end end ``` Use `Tesla.OpenAPI.QueryString.raw!/2` when the OpenAPI media type already produced the exact query string. Do not send `Tesla.OpenAPI.QueryString` through `Tesla.Middleware.Query` as a normal query map in `:modern` mode, which expects request values backed by `Tesla.OpenAPI.QueryParams` in `t:Tesla.Env.private/0`. ## Mapping OpenAPI fields Use the parameter location to choose the Tesla API. Then map only the serialization fields that Tesla needs at request time: | OpenAPI field | Tesla mapping | | --- | --- | | `name` | Constructor argument, except `querystring`, where the whole query string is the value | | `in` | Chooses the Tesla API; it is not passed as an option | | `style` | `:style` atom | | `explode` | `:explode` boolean | | `allowReserved` | `:allow_reserved` boolean where supported | | `required`, `deprecated`, `schema`, `content` | Code generation or validation concern, not a Tesla serialization option | OpenAPI style names that do not belong to a parameter location are not accepted by the corresponding Tesla value object. Tesla options use Elixir atoms and snake case, so OpenAPI `pipeDelimited`, `deepObject`, and `allowReserved` become `:pipe_delimited`, `:deep_object`, and `:allow_reserved`. `schema.additionalProperties` affects the value a generated client accepts for an object parameter. It does not become a `Tesla.OpenAPI.QueryParam` option. For a generated-operation walkthrough, see [Working with OpenAPI parameters](../howtos/openapi-parameters.md). For quick lookup while implementing generated clients, see the [OpenAPI Cheat Sheet](../cheatsheets/openapi.cheatmd).