Skip to content

OpenAPI Sources ​

The @source api capability handle lets you connect to any HTTP API described by an OpenAPI 3.x spec. The compiler validates operation names against the spec at compile time; the runtime executes requests using the proven HTTP infrastructure.

Declaring an API handle ​

aivi
use aivi.api (
    ApiSource
    BearerToken
)

domain Duration over Int = {
    suffix sec
    type sec : Int
    sec = value => Duration value
}

value serverUrl : Text = "https://api.petstore.io/v2"
value apiToken : Text = "secret"

@source api "manual/examples/petstore.yaml" with {
    baseUrl: serverUrl,
    auth: BearerToken apiToken,
    timeout: 30sec
}
signal petstore : ApiSource
  • The first argument is the path to the OpenAPI spec file (YAML or JSON). The current compiler reads it from the workspace invocation directory and uses it for validation; the runtime uses baseUrl.
  • The with { ... } block accepts standard HTTP options (timeout, retry, headers, refreshEvery, decode, refreshOn, activeWhen) plus two API-specific options:
OptionTypePurpose
baseUrlTextRequired. Base URL prepended to operation paths at runtime.
authApiAuthOptional. Injects authentication headers from an ApiAuth sum value.

Using handle members ​

Member access on a handle is validated against the spec's operationIds at compile time.

Read operations (GET) — use as signal ​

aivi
type Pet = {
    id: Int,
    name: Text,
    status: Option Text
}

signal allPets : Signal (Result ApiError (List Pet)) = petstore.listPets

listPets maps to GET /pets in the spec. The compiler checks that listPets is a real operationId and that it is a GET/HEAD/OPTIONS operation. The signal is backed by api.get at runtime.

Write operations (POST / PUT / PATCH / DELETE) — use as value ​

aivi
type NewPet = {
    name: Text,
    status: Option Text
}

value createNewPet : Text -> Text -> Task Text Text = petstore.createPet

createPet maps to POST /pets in the spec. The compiler lowers this to an HttpPost intrinsic call with the composed URL. The current mutation task surface is still the low-level text request adapter shown above; generated request/response records do not yet change that task signature.

Generating type declarations ​

Use aivi openapi-gen to derive AIVI type declarations from the spec schemas:

sh
aivi openapi-gen ./petstore.yaml -o types/petstore.aivi

The generated file contains:

  • A record type for each component schema.
  • A type ApiError = ... with standard error constructors.
  • A type ApiAuth = ... with auth variants matching the spec's security schemes.
  • A handle type alias (type Petstore = Unit).

You can then import the generated types in your module. The generated module path matches the output file you passed to aivi openapi-gen — for example, if you wrote the output to types/petstore.aivi, import from that module:

aivi-fragment
use types.petstore (
    Pet
    NewPet
    ApiError
    ApiAuth
)

Authentication ​

The auth option accepts an ApiAuth sum value imported from aivi.api:

VariantHTTP effect
BearerToken TextAuthorization: Bearer <token> header
BasicAuth Text TextAuthorization: Basic <base64(user:pass)> header
ApiKey TextX-API-Key: <key> header
ApiKeyQuery TextKey appended as query parameter (runtime: deferred)
OAuth2 TextAuthorization: Bearer <token> header

The three checked fragments above form one complete module; the manual verifier compiles them together against manual/examples/petstore.yaml.

See also ​

(c) 2026 by Andreas Herd