# List event sources

Lists the event sources an automation's rule may watch, each with its configuration schema, its data fields, and this owner's current ability to use it. Reading the catalog does not fetch a live value or create a connection.

`GET /v1/users/{userId}/automation-sources`

## Authentication

Both headers are required.

- Header: `X-Api-Key: YOUR_API_KEY`
- Header: `Authorization: Bearer YOUR_USER_TOKEN`

## Path parameters



```json
[
  {
    "schema": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    },
    "in": "path",
    "name": "userId",
    "required": true,
    "description": "The user in the path; must equal the token's own account."
  }
]
```


## Request example

Illustrative request. Replace the host, credentials and resource IDs with your own. If a request file is shown, create it from the schema above. Review the requested action before sending it.

```sh
curl --request GET 'https://api.example.test/v1/users/YOUR_USER_ID/automation-sources' \
  --header 'X-Api-Key: YOUR_API_KEY' \
  --header 'Authorization: Bearer YOUR_USER_TOKEN'
```

## Responses

### 200

The event sources an automation may watch.



```json
{
  "description": "The event sources an automation may watch.",
  "content": {
    "application/json": {
      "schema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AutomationSource"
            },
            "description": "This page's rows."
          },
          "nextCursor": {
            "description": "The cursor for the next page; null once there are no more rows.",
            "type": [
              "string",
              "null"
            ]
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "How many rows the list holds in all."
          }
        },
        "required": [
          "data",
          "nextCursor",
          "total"
        ]
      }
    }
  }
}
```


### 400

The request could not be read as this operation expects.

- `invalid_input` — the body or query failed validation; `issues` names each field
- `invalid_cursor` — the `cursor` is not one this list minted



```json
{
  "description": "The request could not be read as this operation expects.\n\n- `invalid_input` — the body or query failed validation; `issues` names each field\n- `invalid_cursor` — the `cursor` is not one this list minted",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 401

A credential is missing, invalid or expired.

- `partner_key_required` — no `X-Api-Key` header was sent
- `partner_key_invalid` — the `X-Api-Key` is unknown or revoked
- `credential_expired` — the user token has expired; obtain a fresh one



```json
{
  "description": "A credential is missing, invalid or expired.\n\n- `partner_key_required` — no `X-Api-Key` header was sent\n- `partner_key_invalid` — the `X-Api-Key` is unknown or revoked\n- `credential_expired` — the user token has expired; obtain a fresh one",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 403

The credentials are valid but may not do this.

- `subject_mismatch` — the `{userId}` in the path is not the token's user
- `account_disabled` — an operator disabled the account
- `origin_rejected` — a browser `Origin` other than the configured web origin



```json
{
  "description": "The credentials are valid but may not do this.\n\n- `subject_mismatch` — the `{userId}` in the path is not the token's user\n- `account_disabled` — an operator disabled the account\n- `origin_rejected` — a browser `Origin` other than the configured web origin",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 404

The resource is missing, belongs to someone else, or its id is malformed: all three answer alike.



```json
{
  "description": "The resource is missing, belongs to someone else, or its id is malformed: all three answer alike.",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 412

The identity is verified but has no account yet.

- `account_not_provisioned` — the identity is verified but has no account yet; call `users.ensure` first



```json
{
  "description": "The identity is verified but has no account yet.\n\n- `account_not_provisioned` — the identity is verified but has no account yet; call `users.ensure` first",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 429

A limiter refused the request; honour `Retry-After`.

- `rate_limited` — the per-key or per-user limit is spent; honour `Retry-After`



```json
{
  "description": "A limiter refused the request; honour `Retry-After`.\n\n- `rate_limited` — the per-key or per-user limit is spent; honour `Retry-After`",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 500

A fault on our side; quote `requestId` when reporting it.

- `internal` — a fault on our side; quote `requestId` when reporting it



```json
{
  "description": "A fault on our side; quote `requestId` when reporting it.\n\n- `internal` — a fault on our side; quote `requestId` when reporting it",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 503

The replica is draining or a dependency did not answer; `retryable` says whether to try again.

- `internal` — a fault on our side; quote `requestId` when reporting it



```json
{
  "description": "The replica is draining or a dependency did not answer; `retryable` says whether to try again.\n\n- `internal` — a fault on our side; quote `requestId` when reporting it",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


## Complete OpenAPI definition

The exact operation and all referenced components, including recursive schemas.



```json
{
  "operation": {
    "operationId": "automationSources.list",
    "summary": "List event sources",
    "tags": [
      "automations"
    ],
    "description": "Lists the event sources an automation's rule may watch, each with its configuration schema, its data fields, and this owner's current ability to use it. Reading the catalog does not fetch a live value or create a connection.",
    "parameters": [
      {
        "schema": {
          "type": "string",
          "format": "uuid",
          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
        },
        "in": "path",
        "name": "userId",
        "required": true,
        "description": "The user in the path; must equal the token's own account."
      }
    ],
    "security": [
      {
        "apiKey": [],
        "userToken": []
      }
    ],
    "responses": {
      "200": {
        "description": "The event sources an automation may watch.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AutomationSource"
                  },
                  "description": "This page's rows."
                },
                "nextCursor": {
                  "description": "The cursor for the next page; null once there are no more rows.",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "total": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "description": "How many rows the list holds in all."
                }
              },
              "required": [
                "data",
                "nextCursor",
                "total"
              ]
            }
          }
        }
      },
      "400": {
        "$ref": "#/components/responses/InvalidInput"
      },
      "401": {
        "$ref": "#/components/responses/Unauthorized"
      },
      "403": {
        "$ref": "#/components/responses/Forbidden"
      },
      "404": {
        "$ref": "#/components/responses/NotFound"
      },
      "412": {
        "$ref": "#/components/responses/AccountNotProvisioned"
      },
      "429": {
        "$ref": "#/components/responses/TooManyRequests"
      },
      "500": {
        "$ref": "#/components/responses/Internal"
      },
      "503": {
        "$ref": "#/components/responses/Unavailable"
      }
    }
  },
  "components": {
    "schemas": {
      "AutomationSource": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9_.-]{0,79}$",
            "description": "The operation's id within the catalog."
          },
          "version": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991,
            "description": "The operation's version."
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "description": "A short display name for this source."
          },
          "description": {
            "type": "string",
            "maxLength": 2048,
            "description": "What this source reads, in the catalog's own words."
          },
          "semanticIdentity": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048,
            "description": "What this operation actually reads, independent of its exact configuration; used to tell equivalent sources apart."
          },
          "schemaFingerprint": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$",
            "description": "A content hash of this operation's exact configuration and result field types, derived from the registry."
          },
          "configSchema": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "const": "object",
                "description": "Always `object`: a source's configuration is a flat set of named fields."
              },
              "properties": {
                "type": "object",
                "propertyNames": {
                  "type": "string",
                  "pattern": "^[A-Za-z_][A-Za-z0-9_-]{0,63}$"
                },
                "additionalProperties": {
                  "anyOf": [
                    {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "title": {
                              "description": "A short label for this configuration field, for display.",
                              "type": "string",
                              "maxLength": 120
                            },
                            "description": {
                              "description": "Help text for this configuration field, for display.",
                              "type": "string",
                              "maxLength": 2048
                            },
                            "type": {
                              "type": "string",
                              "const": "string",
                              "description": "A text value."
                            },
                            "enum": {
                              "description": "The exact values allowed, when this field is closed to a fixed list.",
                              "minItems": 1,
                              "maxItems": 128,
                              "type": "array",
                              "items": {
                                "type": "string",
                                "maxLength": 4096
                              }
                            },
                            "minLength": {
                              "description": "The shortest allowed length, in characters.",
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 4096
                            },
                            "maxLength": {
                              "description": "The longest allowed length, in characters.",
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 4096
                            },
                            "pattern": {
                              "description": "A regular expression this field's value must match, when its shape is constrained.",
                              "type": "string",
                              "maxLength": 1024
                            },
                            "default": {
                              "description": "The value used when this field is left unset.",
                              "type": "string",
                              "maxLength": 4096
                            }
                          },
                          "required": [
                            "type"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "title": {
                              "description": "A short label for this configuration field, for display.",
                              "type": "string",
                              "maxLength": 120
                            },
                            "description": {
                              "description": "Help text for this configuration field, for display.",
                              "type": "string",
                              "maxLength": 2048
                            },
                            "type": {
                              "type": "string",
                              "const": "boolean",
                              "description": "A true/false value."
                            },
                            "default": {
                              "description": "The value used when this field is left unset.",
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "type"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "title": {
                              "description": "A short label for this configuration field, for display.",
                              "type": "string",
                              "maxLength": 120
                            },
                            "description": {
                              "description": "Help text for this configuration field, for display.",
                              "type": "string",
                              "maxLength": 2048
                            },
                            "type": {
                              "type": "string",
                              "const": "integer",
                              "description": "A whole-number value."
                            },
                            "minimum": {
                              "description": "The smallest allowed value.",
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            "maximum": {
                              "description": "The largest allowed value.",
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            "enum": {
                              "description": "The exact values allowed, when this field is closed to a fixed list.",
                              "minItems": 1,
                              "maxItems": 128,
                              "type": "array",
                              "items": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              }
                            },
                            "default": {
                              "description": "The value used when this field is left unset.",
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            }
                          },
                          "required": [
                            "type"
                          ]
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "title": {
                          "description": "A short label for this configuration field, for display.",
                          "type": "string",
                          "maxLength": 120
                        },
                        "description": {
                          "description": "Help text for this configuration field, for display.",
                          "type": "string",
                          "maxLength": 2048
                        },
                        "type": {
                          "type": "string",
                          "const": "array",
                          "description": "A list of scalar values."
                        },
                        "items": {
                          "oneOf": [
                            {
                              "type": "object",
                              "properties": {
                                "title": {
                                  "description": "A short label for this configuration field, for display.",
                                  "type": "string",
                                  "maxLength": 120
                                },
                                "description": {
                                  "description": "Help text for this configuration field, for display.",
                                  "type": "string",
                                  "maxLength": 2048
                                },
                                "type": {
                                  "type": "string",
                                  "const": "string",
                                  "description": "A text value."
                                },
                                "enum": {
                                  "description": "The exact values allowed, when this field is closed to a fixed list.",
                                  "minItems": 1,
                                  "maxItems": 128,
                                  "type": "array",
                                  "items": {
                                    "type": "string",
                                    "maxLength": 4096
                                  }
                                },
                                "minLength": {
                                  "description": "The shortest allowed length, in characters.",
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 4096
                                },
                                "maxLength": {
                                  "description": "The longest allowed length, in characters.",
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 4096
                                },
                                "pattern": {
                                  "description": "A regular expression this field's value must match, when its shape is constrained.",
                                  "type": "string",
                                  "maxLength": 1024
                                },
                                "default": {
                                  "description": "The value used when this field is left unset.",
                                  "type": "string",
                                  "maxLength": 4096
                                }
                              },
                              "required": [
                                "type"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "title": {
                                  "description": "A short label for this configuration field, for display.",
                                  "type": "string",
                                  "maxLength": 120
                                },
                                "description": {
                                  "description": "Help text for this configuration field, for display.",
                                  "type": "string",
                                  "maxLength": 2048
                                },
                                "type": {
                                  "type": "string",
                                  "const": "boolean",
                                  "description": "A true/false value."
                                },
                                "default": {
                                  "description": "The value used when this field is left unset.",
                                  "type": "boolean"
                                }
                              },
                              "required": [
                                "type"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "title": {
                                  "description": "A short label for this configuration field, for display.",
                                  "type": "string",
                                  "maxLength": 120
                                },
                                "description": {
                                  "description": "Help text for this configuration field, for display.",
                                  "type": "string",
                                  "maxLength": 2048
                                },
                                "type": {
                                  "type": "string",
                                  "const": "integer",
                                  "description": "A whole-number value."
                                },
                                "minimum": {
                                  "description": "The smallest allowed value.",
                                  "type": "integer",
                                  "minimum": -9007199254740991,
                                  "maximum": 9007199254740991
                                },
                                "maximum": {
                                  "description": "The largest allowed value.",
                                  "type": "integer",
                                  "minimum": -9007199254740991,
                                  "maximum": 9007199254740991
                                },
                                "enum": {
                                  "description": "The exact values allowed, when this field is closed to a fixed list.",
                                  "minItems": 1,
                                  "maxItems": 128,
                                  "type": "array",
                                  "items": {
                                    "type": "integer",
                                    "minimum": -9007199254740991,
                                    "maximum": 9007199254740991
                                  }
                                },
                                "default": {
                                  "description": "The value used when this field is left unset.",
                                  "type": "integer",
                                  "minimum": -9007199254740991,
                                  "maximum": 9007199254740991
                                }
                              },
                              "required": [
                                "type"
                              ]
                            }
                          ],
                          "description": "The type each item in the list must match."
                        },
                        "minItems": {
                          "description": "The fewest items allowed.",
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 64
                        },
                        "maxItems": {
                          "description": "The most items allowed.",
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 64
                        }
                      },
                      "required": [
                        "type",
                        "items"
                      ]
                    }
                  ]
                },
                "description": "Each configuration field this source accepts, keyed by field name."
              },
              "required": {
                "default": [],
                "description": "Which configuration fields must be set.",
                "maxItems": 64,
                "type": "array",
                "items": {
                  "type": "string",
                  "pattern": "^[A-Za-z_][A-Za-z0-9_-]{0,63}$"
                }
              },
              "additionalProperties": {
                "type": "boolean",
                "const": false,
                "description": "Always `false`: no configuration field outside `properties` is accepted."
              }
            },
            "required": [
              "type",
              "properties",
              "required",
              "additionalProperties"
            ],
            "description": "This source's configuration, as a bounded JSON Schema subset the generic source editor can render."
          },
          "fields": {
            "minItems": 1,
            "maxItems": 64,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "path": {
                  "minItems": 1,
                  "maxItems": 8,
                  "type": "array",
                  "items": {
                    "type": "string",
                    "pattern": "^[A-Za-z_][A-Za-z0-9_-]{0,63}$"
                  },
                  "description": "The keys to walk, in order, from an observation's top level down to this field."
                },
                "valueType": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "boolean",
                          "description": "A true/false value."
                        }
                      },
                      "required": [
                        "type"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "string",
                          "description": "A text value."
                        }
                      },
                      "required": [
                        "type"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "integer",
                          "description": "A whole-number value, compared exactly."
                        },
                        "unit": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64,
                          "description": "The unit an integer or decimal value is measured in, as the source or literal declares it."
                        }
                      },
                      "required": [
                        "type",
                        "unit"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "decimal",
                          "description": "An exact decimal value, as text, compared exactly."
                        },
                        "unit": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64,
                          "description": "The unit an integer or decimal value is measured in, as the source or literal declares it."
                        }
                      },
                      "required": [
                        "type",
                        "unit"
                      ]
                    }
                  ],
                  "description": "What type this field's value has, and the unit it carries when it has one."
                },
                "optional": {
                  "description": "Whether the provider may genuinely not observe this field, rather than fail to read it. When true, a missing value resolves a condition over it to `missing_field` and the rule's verdict to `unknown`, rather than zero, null or false.",
                  "type": "boolean"
                }
              },
              "required": [
                "path",
                "valueType"
              ],
              "description": "One data field an event or a source's observation carries: where it lives, and its type."
            },
            "description": "The data fields this source's observations carry."
          },
          "public": {
            "type": "boolean",
            "description": "Whether this source reads data anyone can read, rather than data scoped to the owner's own connection."
          },
          "requiredConnectionScopes": {
            "maxItems": 64,
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "description": "The connection scopes a binding needs before this source is available, when it needs any."
          },
          "supportedSubjects": {
            "type": "object",
            "properties": {
              "subjects": {
                "maxItems": 64,
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "description": "The subjects this source can be configured to read, when it is bounded to a known list."
              },
              "assets": {
                "maxItems": 64,
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "description": "The assets this source can be configured to read, when it is bounded to a known list."
              },
              "networks": {
                "maxItems": 64,
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "description": "The networks this source can be configured to read, when it is bounded to a known list."
              },
              "filters": {
                "maxItems": 64,
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "description": "The other filters this source accepts, when it is bounded to a known list."
              }
            },
            "required": [
              "subjects",
              "assets",
              "networks",
              "filters"
            ],
            "description": "What this source can be configured to read, where the catalog knows the bounds; empty where any value is accepted."
          },
          "guarantees": {
            "type": "object",
            "properties": {
              "minCadenceSeconds": {
                "type": "integer",
                "minimum": 0,
                "maximum": 2147483,
                "description": "The shortest interval between requests the provider permits, in seconds."
              },
              "expectedLatencySeconds": {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 2147483
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "How stale the provider's own value may be when it answers, in seconds; null when the provider establishes no bound. A reader with a delivery deadline cannot use a source that promises nothing here."
              },
              "maxAgeSeconds": {
                "type": "integer",
                "minimum": 0,
                "maximum": 2147483,
                "description": "Maximum snapshot observation age accepted at collection. This acquisition guarantee does not shorten a reader's separately declared evaluation-age window."
              },
              "requestsPerMinute": {
                "anyOf": [
                  {
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "The provider's own rate limit for this source, when it publishes one."
              },
              "observationReuseSeconds": {
                "description": "How long one provider observation may serve every reader watching the same subject under the same connection, in seconds. Absent or 0 means each reader causes its own request. A reused observation keeps the provider's own `sourceTime`, so declared freshness still governs; what reuse changes is how often the provider is asked, not how old an accepted observation may be. Keep it at or below the cadence readers are expected to poll at.",
                "type": "integer",
                "minimum": 0,
                "maximum": 2147483
              },
              "batchLimit": {
                "description": "How many distinct subjects the provider can serve in one request. Absent or 1 means no batching. Only providers implementing `readBatch` may declare more: the framework cannot infer that an API accepts several subjects.",
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 1000
              }
            },
            "required": [
              "minCadenceSeconds",
              "expectedLatencySeconds",
              "maxAgeSeconds",
              "requestsPerMinute"
            ],
            "description": "What an operation promises about the snapshots it serves: cadence, freshness and how many subjects it can batch. Describes sampled state; nothing here promises that a change between two polls was seen."
          },
          "presentation": {
            "type": "object",
            "properties": {
              "subjectConfigKey": {
                "description": "Which configuration field names the subject being watched, when the editor should highlight one.",
                "type": "string",
                "pattern": "^[A-Za-z_][A-Za-z0-9_-]{0,63}$"
              },
              "fields": {
                "minItems": 1,
                "maxItems": 64,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "minItems": 1,
                      "maxItems": 8,
                      "type": "array",
                      "items": {
                        "type": "string",
                        "pattern": "^[A-Za-z_][A-Za-z0-9_-]{0,63}$"
                      },
                      "description": "The keys to walk, in order, from an observation's top level down to this field."
                    },
                    "label": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 120,
                      "description": "A short display label for this field."
                    }
                  },
                  "required": [
                    "path",
                    "label"
                  ]
                },
                "description": "Reviewed display labels for a subset of this source's fields."
              }
            },
            "required": [
              "fields"
            ],
            "description": "Reviewed display copy for the source editor: cosmetic only, never part of an execution descriptor or a saved source pin."
          },
          "recipe": {
            "type": "object",
            "properties": {
              "version": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991,
                "description": "The recipe description's own version, bumped when its steps change."
              },
              "title": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120,
                "description": "The recipe's short label, for the reviewed catalog."
              },
              "summary": {
                "type": "string",
                "minLength": 1,
                "maxLength": 600,
                "description": "What the recipe does, for the reviewed catalog."
              },
              "steps": {
                "minItems": 1,
                "maxItems": 12,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "pattern": "^[a-z][a-z0-9_-]{0,47}$",
                      "description": "The step's identifier, unique within its recipe."
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "request",
                        "validate",
                        "calculate"
                      ],
                      "description": "What this step does: `request` calls the provider, `validate` checks what it returned, `calculate` derives a value from earlier steps."
                    },
                    "title": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 120,
                      "description": "The step's short label, for the reviewed catalog."
                    },
                    "description": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 600,
                      "description": "What this step does, for the reviewed catalog."
                    },
                    "api": {
                      "type": "object",
                      "properties": {
                        "method": {
                          "type": "string",
                          "enum": [
                            "GET",
                            "POST",
                            "GRAPHQL"
                          ],
                          "description": "The request's method or protocol."
                        },
                        "resource": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 160,
                          "pattern": "^\\/?[A-Za-z0-9_{}][A-Za-z0-9_./{} -]*$",
                          "description": "The request's path or resource name."
                        }
                      },
                      "required": [
                        "method",
                        "resource"
                      ],
                      "description": "The request this step makes, when it calls the provider."
                    }
                  },
                  "required": [
                    "id",
                    "kind",
                    "title",
                    "description"
                  ]
                },
                "description": "The recipe's steps, in order."
              },
              "limitations": {
                "maxItems": 6,
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 600
                },
                "description": "What the recipe does not cover, in the reviewer's own words."
              },
              "fingerprint": {
                "type": "string",
                "pattern": "^[a-f0-9]{64}$",
                "description": "A content hash identifying this exact recipe, independent of execution or connection identity."
              }
            },
            "required": [
              "version",
              "title",
              "summary",
              "steps",
              "limitations",
              "fingerprint"
            ],
            "description": "A reviewed, public description of how a source is collected: the steps a reviewer confirmed, never an executable request or a resolved private endpoint."
          },
          "availability": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "available",
                  "needs_connection",
                  "unavailable",
                  "unknown"
                ],
                "description": "Whether this source is usable for the current owner: `available` ready to use, `needs_connection` a connection must be granted first, `unknown` availability has not been checked yet, or an earlier check's validity window has expired. `unavailable` marks a source this deployment cannot offer at all; `automationSources.list` never returns it today."
              },
              "configured": {
                "type": "boolean",
                "description": "Whether the owner has set up a connection for this source."
              },
              "verified": {
                "type": "boolean",
                "description": "Whether that connection has been confirmed to work."
              },
              "grantedScopes": {
                "maxItems": 64,
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "description": "The connection scopes the owner has actually granted."
              },
              "checkedAt": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "When availability was last checked, when it has been."
              },
              "expiresAt": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "When this availability check expires and must be re-checked, when it has an expiry."
              },
              "reason": {
                "anyOf": [
                  {
                    "type": "string",
                    "maxLength": 2048
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Why this source is not available, when it is not."
              }
            },
            "required": [
              "status",
              "configured",
              "verified",
              "grantedScopes",
              "checkedAt",
              "expiresAt",
              "reason"
            ],
            "description": "This owner's ability to use this source right now: whether it is connected and verified. Carries no credential, account or provider connection identifier."
          }
        },
        "required": [
          "id",
          "version",
          "label",
          "description",
          "semanticIdentity",
          "schemaFingerprint",
          "configSchema",
          "fields",
          "public",
          "requiredConnectionScopes",
          "supportedSubjects",
          "guarantees",
          "availability"
        ],
        "description": "One event source an automation may watch: its configuration schema, its data fields, and this owner's current ability to use it."
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "The kind of problem as a URN, `urn:fin:error:<kind>`; stable, compare against it"
          },
          "title": {
            "type": "string",
            "description": "The kind's human title, for logs; never parse it"
          },
          "status": {
            "type": "integer",
            "minimum": 400,
            "maximum": 599,
            "description": "The HTTP status, repeated in the body"
          },
          "reason": {
            "description": "The machine-readable why. One of:\n\n- `run_active` (409) — a run already holds this conversation\n- `budget_exhausted` (409) — the user's spend headroom is gone, or an operator froze it\n- `approval_not_pending` (409) — the approval was already decided or has expired, or its id does not exist or belongs to a different conversation\n- `execution_capacity` (409) — no execution capacity is free right now; `retryable` says whether to try again\n- `execution_unavailable` (409) — the execution engine could not take the work\n- `stop_pending` (409) — a stop is already in progress and its cleanup is not yet confirmed\n- `automation_changed` (409) — the `revision` sent is stale; reload the automation\n- `automation_held` (409) — an operator holds the automation; it fires again when released\n- `automation_invalid` (409) — the automation's definition cannot run as written\n- `automation_completed` (409) — the automation has finished for good and cannot fire again\n- `automation_limit` (409) — the user already has as many automations as the deployment allows\n- `profile_unknown_tool` (409) — the run profile names a tool this deployment does not have\n- `deployment_paused` (409) — an operator paused a deployment control; nothing was admitted or fired\n- `run_not_active` (409) — the run named in the path is not the conversation's live run\n- `withdrawal_changed` (409) — the withdrawal cannot be prepared or confirmed as asked: the balance no longer covers it, its terms changed or expired, or it is already in progress\n- `credential_expired` (401) — the user token has expired; obtain a fresh one\n- `account_disabled` (403) — an operator disabled the account\n- `account_not_provisioned` (412) — the identity is verified but has no account yet; call `users.ensure` first\n- `provider_unavailable` (503) — an external provider the call depends on did not answer\n- `engine_unavailable` (503) — the execution engine did not answer\n- `invalid_input` (400) — the body or query failed validation; `issues` names each field\n- `internal` (500) — a fault on our side; quote `requestId` when reporting it\n- `partner_key_required` (401) — no `X-Api-Key` header was sent\n- `partner_key_invalid` (401) — the `X-Api-Key` is unknown or revoked\n- `subject_mismatch` (403) — the `{userId}` in the path is not the token's user\n- `origin_rejected` (403) — a browser `Origin` other than the configured web origin\n- `permission_required` (403) — the operator credential lacks the scope this call needs\n- `rate_limited` (429) — the per-key or per-user limit is spent; honour `Retry-After`\n- `stream_capacity` (429) — no stream socket is free on this replica or for this user; honour `Retry-After`\n- `invalid_cursor` (400) — the `cursor` is not one this list minted",
            "type": "string",
            "enum": [
              "run_active",
              "budget_exhausted",
              "approval_not_pending",
              "execution_capacity",
              "execution_unavailable",
              "stop_pending",
              "automation_changed",
              "automation_held",
              "automation_invalid",
              "automation_completed",
              "automation_limit",
              "profile_unknown_tool",
              "deployment_paused",
              "run_not_active",
              "withdrawal_changed",
              "credential_expired",
              "account_disabled",
              "account_not_provisioned",
              "provider_unavailable",
              "engine_unavailable",
              "invalid_input",
              "internal",
              "partner_key_required",
              "partner_key_invalid",
              "subject_mismatch",
              "origin_rejected",
              "permission_required",
              "rate_limited",
              "stream_capacity",
              "invalid_cursor"
            ]
          },
          "requestId": {
            "type": "string",
            "description": "The id Fin used for this request; quote it when reporting a problem"
          },
          "retryable": {
            "type": "boolean",
            "description": "Whether repeating the same request later can succeed without changing it"
          },
          "detail": {
            "description": "Only on `invalid_input`: which part of the request failed validation",
            "type": "string"
          },
          "issues": {
            "description": "Only on `invalid_input`: one entry per failing field",
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "path": {
                  "type": "string",
                  "description": "The JSON pointer of the failing field; empty for the root object"
                },
                "message": {
                  "type": "string",
                  "description": "Why the field failed"
                }
              },
              "required": [
                "path",
                "message"
              ]
            }
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "requestId",
          "retryable"
        ],
        "description": "RFC 9457 problem details: what every error response carries. Never a provider's message, a query or a stack."
      }
    },
    "responses": {
      "InvalidInput": {
        "description": "The request could not be read as this operation expects.\n\n- `invalid_input` — the body or query failed validation; `issues` names each field\n- `invalid_cursor` — the `cursor` is not one this list minted",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "A credential is missing, invalid or expired.\n\n- `partner_key_required` — no `X-Api-Key` header was sent\n- `partner_key_invalid` — the `X-Api-Key` is unknown or revoked\n- `credential_expired` — the user token has expired; obtain a fresh one",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The credentials are valid but may not do this.\n\n- `subject_mismatch` — the `{userId}` in the path is not the token's user\n- `account_disabled` — an operator disabled the account\n- `origin_rejected` — a browser `Origin` other than the configured web origin",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "NotFound": {
        "description": "The resource is missing, belongs to someone else, or its id is malformed: all three answer alike.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "AccountNotProvisioned": {
        "description": "The identity is verified but has no account yet.\n\n- `account_not_provisioned` — the identity is verified but has no account yet; call `users.ensure` first",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "A limiter refused the request; honour `Retry-After`.\n\n- `rate_limited` — the per-key or per-user limit is spent; honour `Retry-After`",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "Internal": {
        "description": "A fault on our side; quote `requestId` when reporting it.\n\n- `internal` — a fault on our side; quote `requestId` when reporting it",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "Unavailable": {
        "description": "The replica is draining or a dependency did not answer; `retryable` says whether to try again.\n\n- `internal` — a fault on our side; quote `requestId` when reporting it",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      },
      "userToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  }
}
```

