SPEC EXTENSION

Package

A schema for organizing, documenting, and validating endpoints. A package facilitates endpoint discovery and integration by providing standardized metadata about them.

Introduction

The Web Function Package specification simplifies endpoint interaction by standardizing their description and access. This defined structure ensures all endpoints are consistent, discoverable, and self-documented.

Package definition

A package is a JSON object that contains the following keys:

Key and typeDescription
base_url
string
Required. Base URL for the package. MUST use the HTTP or HTTPS scheme.
event_source_url
string
Optional. An event source URL from which to receive server-sent-events. See the event specification for more information.
pipeline_url
string
Optional. A function pipelining URL. See the pipelining specification for more information.
name
string
Optional. The name of the package.
flags
array of strings
Optional. List of package flags. See the available flags section below for a complete list of flags available at the package level.
version
string
Optional. The version that this package describes. An opaque string. MUST be present when the versioned flag is set. See the versioning specification for more information.
versions
array of strings
Optional. The versions that are available. Each entry is an opaque string. MUST be present when the versioned flag is set. See the versioning specification for more information.
docs
string
Optional. Top-level documentation for the package. MUST be formatted as markdown.
endpoints
array of objects
Required. An array of endpoint definitions, as described below.
events
array of objects
Optional. An array of events definitions, as described below. See the event specification for more information.
errors
array of objects
Optional. A list of common ERROR_CODEs that can be returned by any endpoints in this package. Note that clients SHOULD only refer to this list if an endpoint uses the error_triple flag. See the error specification for more information.
objects
array of objects
Optional. A list of named object definitions, as described below. Each definition can be referenced as a refined object type (object.<name>) anywhere a type is expected. See the types section for more information.

Types

Everywhere a type is expected—an endpoint's returns, or an argument's or attribute's type—it is expressed using the following grammar.

A type is one of:

  • A base JSON type, written as a bare string: object, array, string, number, boolean, or null. The bare string array means an array of any.
  • The special any type, which represents any base JSON type. any MUST NOT be refined.
  • A refined type, written as a base type and a refinement joined by a dot, for example number.u32, string.email, or object.user. See the refinements section for the complete list. An object.<name> refinement references a definition in the package's objects array.
  • An array of, written { "array": <type> }. <type> is the type of each item and MAY be a single type or a union. { "array": "object.user" } is an array of users. { "array": ["string", "number"] } is an array of string or number. This is the canonical form.
  • A generic application of a named object, written { "object.<name>": <type> }. Read the generics specification to use it. A package that does not use this form is unchanged.

A returns or type value is either a single type or a union of types. A union is a non-empty JSON array, and a JSON array is a union only in two positions: the value as a whole, and the <type> applied by { "array": <type> } or { "object.<name>": <type> }. A JSON array in any other position is an array of the union of the types inside it.

Empty arrays are not permitted. Duplicate entries in a union are removed, keeping the first occurrence of each entry. A union of one type is that type, so ["string"] is string and ["any"] is any.

The array-of shorthands below are read by converting each JSON array that is not in union position to { "array": <union of its entries> }, then applying the union rules above.

Shorthand Becomes Canonical form
"array"
{ "array": "any" } { "array": "any" }
["array"]
[{ "array": "any" }] { "array": "any" }
[["any"]]
[{ "array": "any" }] { "array": "any" }
[["string", "number"]]
[{ "array": ["string", "number"] }] { "array": ["string", "number"] }

["string", ["object.user"]] is a string or an array of object.user. The same union in canonical form is ["string", { "array": "object.user" }]. The bare "object.user" is a single user object, and "any" matches any value.

Endpoint definition

Each element in the endpoints array is an object that contains the following keys:

Key and typeDescription
name
string
Required. Suffix for the endpoint URL, appended to the PACKAGE_BASE_URL to form the full endpoint URL. Endpoint names MUST be unique within a package; overloading (two endpoints sharing the same name) is not permitted. The name MUST start with a letter and match [a-z][a-z0-9-]*.
returns
string, array, or object
Required. The type(s) returned by the endpoint, expressed using the type grammar: either a single type (for example "object.user" or { "array": "object.user" }) or a non-empty array representing a union.
flags
array of strings
Optional. List of endpoint flags. See the available flags section below for a complete list of flags available at the endpoint level.
group
string
Optional. A name used to categorize or group similar endpoints together. This should be used by documentation tools to organize related endpoints.
docs
string
Optional. Documentation for the endpoint. MUST be formatted as markdown.
errors
array of objects
Optional. A list of specific ERROR_CODE that can be returned by this endpoint. Note that clients SHOULD only refer to this list if an endpoint uses the error_triple flag. See error for more information.
arguments
array of objects
Required. Arguments required by the endpoint, as described below. If no arguments are required, the array should be empty.
attributes
array of objects
Optional. Attributes of the object returned by the endpoint, as described below. This element MAY be present only when returns is (or includes) the bare object type.

URL composition

The full URL of an endpoint is formed by joining the package's base_url and the endpoint's name with exactly one / separator:

  • If base_url ends with a /, the name is appended directly.
  • If base_url does not end with a /, a single / is inserted before the name.
  • An endpoint name MUST NOT contain a /.

For example, given a base_url of https://api.example.com (or, equivalently, https://api.example.com/) and an endpoint name of find-user-by, the full endpoint URL is https://api.example.com/find-user-by.

Event definition

Each element in the events array is an object that contains the following keys:

Key and typeDescription
name
string
Required. The name of the event.
group
string
Optional. A name used to categorize or group similar events together. This should be used by documentation tools to organize related events.
docs
string
Optional. Documentation for the event. MUST be formatted as markdown.
attributes
array of objects
Required. Attributes in the event object, as described below.

Argument definition

Each element in the arguments array is an object that contains the following keys:

Key and typeDescription
name
string
Required. Name of the argument. MUST start with a letter and match [a-z][a-z0-9_]*: one a-z, then zero or more of a-z, 0-9, and _.
type
string, array, or object
Required. The type(s) accepted for the argument, expressed using the type grammar: either a single type (for example "string.email" or { "array": "string.email" }) or a non-empty array representing a union.
group
string
Optional. A name used to categorize or group similar arguments together. This should be used by documentation tools to organize related arguments.
choices
array
Optional. An array specifying the exact, case-sensitive values that are permitted for this argument. Each value in the choices array must conform to one of the types specified in the argument's type key.

Note that if the argument's type is (or includes) the array type, choices may contain strings or numbers representing the allowed values that can be included in the array.
flags
array of strings
Optional. List of argument flags. See the available flags section below for a complete list of flags available at the argument level.
docs
string
Optional. Description of the argument. MUST be formatted as markdown.

Attribute definition

Each element in the attribute array is an object that contains the following keys:

Key and typeDescription
name
string
Required. Name of the attribute. MUST start with a letter and match [a-z][a-z0-9_]*, the same rule as an argument name.
type
string, array, or object
Required. The type(s) of the attribute, expressed using the type grammar: either a single type (for example "string.email" or { "array": "string.email" }) or a non-empty array representing a union.
values
array
Optional. An array specifying the exact, case-sensitive values that could be present in this attribute. Each value in the values array must conform to one of the types specified in the attribute's type key.

Note that if the attribute's type is (or includes) the array type, values may contain strings or numbers representing the allowed values that could be part of the array.
flags
array of strings
Optional. List of attribute flags. See the available flags section below for a complete list of flags available at the attribute level.
docs
string
Optional. Description of the attribute. MUST be formatted as markdown.

Object definition

Each element in the objects array is an object that contains the following keys:

Key and typeDescription
name
string
Required. Name of the object. It is referenced as a refined object type (object.<name>). Object names MUST be unique within a package.
arguments
array of objects
Optional. The object's members when it is referenced in an argument context, each following the argument schema. MUST be present when the object is referenced in an argument context.
attributes
array of objects
Optional. The object's members when it is referenced in an attribute context, each following the attribute schema. MUST be present when the object is referenced in an attribute context.

An object.<name> reference appears in one of two contexts, which determines which set of definitions applies:

  • Argument context — the object is referenced as an argument's type. The object's arguments describe its members.
  • Attribute context — the object is referenced as an endpoint's returns or as an attribute's type. The object's attributes describe its members.

The context propagates recursively: when an argument's or attribute's type references another object, that nested object is interpreted in the same context as the definition that references it. Because an object MAY be referenced in both contexts within the same package, it MAY define both arguments and attributes; each set is used only in its matching context.

Error definition

Each element in the error array is an object that contains the following keys:

Key and typeDescription
code
string
Required. Machine readable code for the error.
docs
string
Optional. Description of the error. The description SHOULD focus on explaining all the situations in which this error will arise. MUST be formatted as markdown.

Available flags

The Type column indicates the level or levels at which each flag may appear. A flag MUST only be used at a level listed for it (package, endpoint, argument, or attribute) and MUST NOT appear at any other level.

NameTypeDescription
versioned
PackageIndicates the package is versioned using the Api-Version header. See the versioning specification for more information.
package
EndpointIndicates the endpoint returns another package definition.
event_source
EndpointIndicates the endpoint returns an event source URL. An endpoint with this flag MUST declare a returns of ["string"]. See the event specification for more information.
error_triple
EndpointIndicates the endpoint adheres to the error response structure as per the error specification. When this flag is set and the response status code is 400, the response body MUST be an array (the error triple), regardless of the endpoint's declared returns type. See the error specification for more information.
bearer_auth
EndpointIndicates the endpoint requires authentication via a bearer token.
capture_bearer
EndpointIndicates the endpoint will return a bearer token in its response. See the authentication specification for more information.
paginated
EndpointIndicates the endpoint supports pagination.
deferred
EndpointIndicates the client sends the same request again when the returned object has defer set to true. wait is the number of milliseconds to wait. When defer is absent or false, the client surfaces the object. Declare defer and wait on that object to type them. See the deferral specification.
private
Endpoint, Argument, AttributeIndicates the endpoint, argument, or attribute is intended for internal use and is not part of the public API. Documentation tooling SHOULD omit the flagged endpoint, argument, or attribute from generated or published documentation.
required
ArgumentIndicates if the argument is mandatory.
nullable
AttributeIndicates the attribute is optional: its key MAY be absent from the object, and when the key is present its value MAY be null. Consumers SHOULD treat a missing key and a null value equivalently.
secret
Argument, AttributeA presentation hint that the value is sensitive. Tooling that supports the flag SHOULD collect the argument with a password input, and SHOULD mask the attribute with an option to reveal it.

Refinements

A refinement narrows a base JSON type, providing more specific constraints than the base JSON types alone. Refinements are particularly useful for languages with strict typing. A refined type is written by joining the base type and the refinement with a dot, for example number.u32 or string.email.

The any type MUST NOT be refined. In addition to the refinements listed below, the object type may be refined with the name of a definition in the package's objects array (object.<name>).

RefinementBase JSON TypeExplanation
u32
numberUnsigned 32-bit integer.
u64
numberUnsigned 64-bit integer.
i32
numberSigned 32-bit integer.
i64
numberSigned 64-bit integer.
f32
number32-bit floating point number.
f64
number64-bit floating point number.
timestamp
numberA UNIX timestamp (seconds since the epoch).
date
stringA date string in ISO 8601 format (e.g., YYYY-MM-DD).
time
stringA time string in ISO 8601 format (e.g., HH:MM:SS).
datetime
stringA date-time string in ISO 8601 format.
uuid
stringA Universally Unique Identifier.
base64
stringA Base64 encoded string.
email
stringAn email address.
phone
stringA phone number in E.164 format.
url
stringA Uniform Resource Locator.
uri
stringA Uniform Resource Identifier.
ipv4
stringAn IPv4 address.
ipv6
stringAn IPv6 address.
hostname
stringA valid hostname as defined by RFC 1123.

Validation requirements

The constraints expressed in the definition tables above—required versus optional keys, value types, allowed values, and flag scoping—are themselves normative and MUST be enforced.

In addition, each package MUST pass the following validations:

  • The base URL MUST be valid as per RFC 3986.
  • All specified types and flags MUST match defined constraints.
  • Every type in a returns or type value MUST be a valid base type, any, a valid refinement, an array of, as described in the types section, or a generic application as defined by the generics specification. Empty arrays are not permitted. A union MUST contain at least one entry.
  • The any type MUST NOT be refined.
  • Each object.<name> refinement MUST resolve to an entry in the package's objects array.
  • An object referenced in an argument context MUST define an arguments array; an object referenced in an attribute context MUST define an attributes array.
  • Object names MUST be unique within the package.
  • An endpoint name MUST start with a letter and match [a-z][a-z0-9-]*.
  • Each argument name MUST start with a letter and match [a-z][a-z0-9_]*.
  • Each attribute name MUST start with a letter and match [a-z][a-z0-9_]*.

Security considerations

Several keys in a package—the docs field on the package, endpoints, events, arguments, attributes, and errors—contain Markdown authored by the API developer. Because a package may be fetched from a third party or generated dynamically, tooling that renders these docs fields MUST treat them as untrusted input. Renderers MUST neutralize embedded scripting and active content (for example, by sanitizing the generated HTML) to avoid cross-site scripting (XSS) and similar injection attacks.

Example

A simple example of a Web Function Package defining a single endpoint might look like this:

{
  "base_url": "https://api.example.com",
  "name": "ExamplePackage",
  "flags": [],
  "docs": "This package defines endpoints for Example API.",
  "errors": [],
  "objects": [
    {
      "name": "user",
      "attributes": [
        {
          "name": "id",
          "type": "string.uuid"
        },
        {
          "name": "email",
          "type": "string.email"
        }
      ]
    }
  ],
  "endpoints": [
    {
      "name": "find-user-by",
      "returns": "object.user",
      "flags": [],
      "group": "users",
      "docs": "Retrieves user data.",
      "errors": [],
      "arguments": [
        {
          "name": "id",
          "type": "string.uuid",
          "choices": [],
          "flags": ["required"],
          "docs": "Identifier of the user."
        }
      ]
    }
  ]
}

Retrieval

A package can reach a client in more than one way, but only one of them is governed by this specification.

  • Invocation response (covered). A Web Function Package MAY be returned as the response body of a Web Function Endpoint invocation, that is, an HTTP POST as described in the endpoint specification. This is the only retrieval method defined by this specification. It enables a dynamic and recursive discovery mechanism where endpoints return packages as part of their operation, supporting complex scenarios where packages are interdependent or where the structure of available APIs can change.

  • Side-loaded (out of scope). A package MAY also be obtained out of band, for example distributed as a static file read from the filesystem, or fetched with a plain HTTP GET. Such a side-loaded package MAY be static or dynamically generated by a web application so its contents adapt to the request or to application state. These mechanisms are common and perfectly valid, but they are not part of this specification: how a side-loaded package is located, transported, or cached is left entirely to the implementation.