Using OpenAPI Specs

Train API functions and webhook handlers from an OpenAPI 3.0+ document with the TypeScript poly CLI.

Important

OpenAPI generate and train run only in the TypeScript poly CLI (npx poly model …). The Python package has no model generate / model train commands today. Python CLI support is on the roadmap.

  • Python-first: train with Using Postman, then python -m polyapi generate.

  • Or install Node, run the commands on this page, then python -m polyapi generate with the same API key and instance.

Important

Poly currently supports OpenAPI Spec 3.0 or higher.

Choose a host URL mode

Each trained function’s HTTP source.url must resolve to a real host. Pick one mode when you generate.

Mode

CLI

Trained functions

Host as argument

--hostUrlAsArgument or --hostUrlAsArgument baseUrl

Required string argument (default name hostUrl). URL templates use {{hostUrl}} / {{baseUrl}}. Callers pass the host on every execute.

Hardcoded host

--hostUrl https://api.example.com

Host is baked into every URL. Callers do not pass a host argument. Value must be a valid HTTP(S) URL.

OAS servers

omit both flags

Use servers from the OpenAPI document. The spec must define exactly one usable server. Otherwise generate fails and you must pass a flag.

Warning

If you generate without --hostUrl or --hostUrlAsArgument and the OAS has no usable servers entry, train can still “succeed” and execute returns 404. The sample spec on this page has no servers block, so the commands below always pass a host flag.

If you set both flags, --hostUrl wins and the host is hardcoded.

Create a Specification Input file

A Specification Input JSON describes the API functions (and webhook handlers) you want to upsert. Create it with npx poly model generate.

Note

If you do not have the poly CLI installed, see Generated SDKs.

Create json-placeholder-spec.yaml:

openapi: 3.0.0
info:
    title: Fake json placeholder spec
    version: 1.0.0
paths:
    /posts:
        post:
            operationId: createPost
            description: Creates a new post.
            requestBody:
                content:
                    application/json:
                        schema:
                            $ref: "#/components/schemas/CreatePost"
            responses:
                "201":
                    description: "Created"
                    content:
                        application/json:
                            schema:
                                $ref: "#/components/schemas/Post"
components:
    schemas:
        Post:
            required:
                - id
                - name
            properties:
                id:
                    type: integer
                    format: int64
                name:
                    type: string
        CreatePost:
            required:
                - name
            properties:
                name:
                    type: string

Generate in host as argument mode so the SDK call below matches the trained signature:

$ npx poly model generate ./json-placeholder-spec.yaml --context "jsonPlaceholder" --hostUrlAsArgument

Empty --hostUrlAsArgument defaults the argument name to hostUrl. To pick a name:

$ npx poly model generate ./json-placeholder-spec.yaml --context "jsonPlaceholder" --hostUrlAsArgument baseUrl

Output filename

The JSON file is named from the OpenAPI info.title, slugified, not from the YAML filename.

For this sample, info.title is Fake json placeholder spec, so generate writes fake-json-placeholder-spec.json.

Always use the path printed by the CLI. If that file already exists, the CLI adds a -N suffix (fake-json-placeholder-spec-1.json, …).

To pin the output path, pass a destination as the second argument:

$ npx poly model generate ./json-placeholder-spec.yaml ./json-placeholder-spec.json --context "jsonPlaceholder" --hostUrlAsArgument

Inspect the JSON: the first argument should be the host string, and source.url should start with {{hostUrl}} (or your custom argument name).

Validate the OpenAPI document before generate if you hit translator errors:

Path, query, and header parameters in the OAS become trained function arguments. See API Function path, query, and header parameters.

See flags:

$ npx poly model generate --help

Other host URL modes

Hardcoded host (single global API; callers do not pass a host):

$ npx poly model generate ./json-placeholder-spec.yaml --context "jsonPlaceholder" --hostUrl "https://jsonplaceholder.typicode.com"

OAS servers (spec must have exactly one usable server; no host flag):

$ npx poly model generate ./spec-with-servers.yaml --context "myApi"

Train API Functions

Upsert every resource in the Specification Input into your environment:

$ npx poly model train ./fake-json-placeholder-spec.json

Warning

Train is an upsert. If an API function or webhook handler already exists with the same name and context, it is overwritten.

Use Your New API Functions

Regenerate the SDK, then call the function. In host-as-argument mode the host is the first argument:

import poly from 'polyapi';

(async () => {

    const response = await poly.jsonPlaceholder.createPost('https://jsonplaceholder.typicode.com', {
        name: 'Foo'
    });

    console.log(response.data);

})();

Run it:

$ npx ts-node ./index.ts

You should see:

{ name: 'Foo', id: 101 }

If you generated with --hostUrl instead, the SDK call has no host argument.

Train Webhook Handlers

You can also import webhooks from an OpenAPI document into Poly as webhook handlers.

The webhooks object was introduced in OpenAPI 3.1.

Here’s an example:

openapi: 3.1.0
info:
    title: Fake json placeholder spec
    version: 1.0.0
webhooks:
    /{id}/events:
        post:
            operationId: onPostCreation
            requestBody:
                description: Information about a new post created into the system.
                content:
                    application/json:
                        schema:
                            $ref: "#/components/schemas/Post"
            responses:
                "200":
                    description: Return a 200 status to indicate that the data was received successfully
components:
    schemas:
        Post:
            required:
                - id
                - name
            properties:
                id:
                    type: integer
                    format: int64
                name:
                    type: string

Tip

You can define both webhooks and APIs in the same OpenAPI document. Poly will parse and import them both.

Define the webhook name and subpath

The webhook subpath is the part of the URL after the webhook id. For example, in https://na1.polyapi.io/webhook/{id}/events, the subpath is /events.

The subpath is optional. Use it to hint what the webhook is for.

Two ways to set name and subpath:

  1. As in the example above: operationId is the webhook name, and the parent key supplies the subpath (/{id}/events). If the parent key contains /, Poly treats it as a subpath.

  2. Put the webhook name in the parent key and set the subpath with x-subpath:

    openapi: 3.1.0
    info:
        title: Fake json placeholder spec
        version: 1.0.0
    webhooks:
        onPostCreation:
            post:
                x-subpath: /{id}/events
                requestBody:
                    description: Information about a new post created into the system.
                    content:
                        application/json:
                            schema:
                                $ref: "#/components/schemas/Post"
                responses:
                    "200":
                        description: Return a 200 status to indicate that the data was received successfully
    components:
        schemas:
            Post:
                required:
                    - id
                    - name
                properties:
                    id:
                        type: integer
                        format: int64
                    name:
                        type: string
    

Modify a Specification Input

After npx poly model generate, edit the JSON before train if you need to change arguments, names, URLs, or schemas.

Example produced by the host-as-argument command above:

{
    "functions": [
        {
            "name": "createPost",
            "context": "jsonPlaceholder",
            "description": "Creates a new post.",
            "arguments": [
                {
                    "name": "hostUrl",
                    "type": "string",
                    "required": true,
                    "description": "Specifies the host URL for the service. It should be a fully qualified URL string that provides the base address of the service endpoint.",
                    "removeIfNotPresentOnExecute": false
                },
                {
                    "name": "body",
                    "type": "object",
                    "typeSchema": {
                        "$schema": "http://json-schema.org/draft-06/schema#",
                        "required": [
                            "name"
                        ],
                        "properties": {
                            "name": {
                                "type": "string"
                            }
                        },
                        "x-readme-ref-name": "CreatePost",
                        "definitions": {}
                    },
                    "required": true,
                    "description": "The payload containing the details of the new blog post. This should include necessary information such as the title, content, author, and any other relevant metadata required by the blog platform.",
                    "removeIfNotPresentOnExecute": false
                }
            ],
            "returnType": "object",
            "returnTypeSchema": {
                "$schema": "http://json-schema.org/draft-06/schema#",
                "required": [
                    "id",
                    "name"
                ],
                "properties": {
                    "id": {
                        "type": "number",
                        "format": "int64"
                    },
                    "name": {
                        "type": "string"
                    }
                },
                "x-readme-ref-name": "Post",
                "definitions": {}
            },
            "source": {
                "auth": {
                    "type": "noauth"
                },
                "method": "POST",
                "body": {
                    "mode": "raw",
                    "raw": "{{body}}",
                    "language": "json"
                },
                "url": "{{hostUrl}}/posts",
                "headers": []
            }
        }
    ],
    "webhooks": []
}

You can edit:

  • arguments

  • name

  • returnTypeSchema

  • source

  • and other fields on the DTOs below

Full field lists:

Validate the JSON after you edit it:

$ npx poly model validate ./fake-json-placeholder-spec.json

Onward

Next:

  • Install the PolyAPI SDK and call this API function from your language.

  • Use Server Functions to coordinate many API functions in code.

See Generated SDKs for language setup, or Functions for which function kind to use.