---
title: "Add an action"
method: POST
path: "/api/v1/org-actions"
tags: ["authed"]
---

# Add an action

`POST /api/v1/org-actions`

## Request

- Base URL: `https://api.teaflask.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.teaflask.com/api/v1/org-actions`
- Auth: none declared

Adds an action to the catalog by hand. The definition is checked in
full, and one whose slug or endpoint the catalog already has, archived
actions included, is refused. Its source is recorded as manual; a
source_ref is not accepted.

## Request body

- RegisterOrgActionRequest
  - `action` object, required: The action's definition: slug, title, description, method, path_template, the JSON Schemas of its path, query and body parameters and of its response, and optionally policy, effect and a GraphQL operation.

## Response `201`

Successful Response

- OrgActionResponse
  - `id` string, uuid, required: The action's id.
  - `organization_id` string, uuid, required: The organization it belongs to.
  - `slug` string, required: The action's unique short name; an agent's configuration grants actions by it, like "cancel-subscription".
  - `title` string, required: A short human-readable name.
  - `description` string, required: What an agent reads when deciding whether to call the action.
  - `method` 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', required: The catalog's method whitelist: an action can only ever speak these.
  - `path_template` string, required: The endpoint path on the organization's own API, with {placeholder} segments for path parameters, like "/api/pets/{pet_id}/".
  - `path_params_schema` object, nullable, required: The JSON Schema of the path placeholders' values; null when there are none.
  - `query_params_schema` object, nullable, required: The JSON Schema of the query parameters; null when none is declared.
  - `body_schema` object, nullable, required: The JSON Schema of the request body; null when none is declared.
  - `response_schema` object, nullable, required: The JSON Schema of the success (2xx) response body, as the API's spec declares it; null when the spec declares none.
  - `policy` 'allow' | 'deny' | 'ask', required
  - `effect` 'read_only' | 'idempotent' | 'destructive', required: What calling the action does to the world — an annotation, never a policy. It feeds the policy default for rows registered without one and the approval gate's prompt tone; an explicit policy always wins, and a mutating method never defaults above ask whatever the annotation claims.
  - `status` 'active' | 'archived', required
  - `source` 'manual' | 'scan' | 'inferred', required
  - `source_ref` union, required: Where a scanned or inferred action came from; null for one registered by hand.
    - SourceRef: Where an action scanned from an API spec committed to a repository came from: the spec file and operation, at a commit.
      - `repo` string, required: The repository the spec lives in.
      - `spec_path` string, required: The spec file's path in that repository.
      - `operation_id` string, required: The operation's id within the spec.
      - `commit_sha` string, required: The commit the spec was read at.
      - `operation_hash` string, required: A fingerprint of the operation, to notice when the spec changes it.
      - `extractor` integer: The version of the scanner that read the spec.
    - InferredSourceRef: Where an action read out of the app's own code came from, when no API spec describes it: the route-handler file, at a commit.
      - `origin` 'inference': Always inference: read from code, not a spec.
      - `repo` string, required: The repository the code lives in.
      - `commit_sha` string, required: The commit the code was read at.
      - `handler_path` string, required: The path of the file that handles the endpoint.
      - `confidence_note` string, nullable: What could not be confirmed from the code; null when nothing was flagged.
    - GeneratedSourceRef: Where an action from an API spec the repository generates (rather than commits) came from: the spec file and operation, at a commit, plus the script that generated the spec.
      - `origin` 'generated': Always generated: read from a generated spec.
      - `repo` string, required: The repository that generates the spec.
      - `spec_path` string, required: The generated spec file's path.
      - `operation_id` string, required: The operation's id within the spec.
      - `commit_sha` string, required: The commit the spec was generated at.
      - `operation_hash` string, required: A fingerprint of the operation, to notice when the spec changes it.
      - `extractor` integer: The version of the scanner that read the spec.
      - `generator_sha256` string, required: A fingerprint of the script that generated the spec.
    - GraphQLSourceRef: Where a discovered GraphQL action came from: the same operation identity a spec ref carries (spec_path is the client project's package.json, operation_id the operation's name) plus the GraphQL evidence. Its extractor version is GraphQL discovery's own.
      - `origin` 'graphql'
      - `repo` string, required
      - `spec_path` string, required
      - `operation_id` string, required
      - `commit_sha` string, required
      - `operation_hash` string, required
      - `extractor` integer
      - `evidence` GraphQLEvidence, required: How a discovered GraphQL operation was read: the file and line it is written at, whether its stored definition order is the one the app executes, its endpoint, the schema it validated against, and any client-only directives that schema does not declare.
        - `evidence_path` string, required
        - `evidence_line` integer, nullable
        - `document_order` 'executed' | 'first_reach_fallback', required: Whether a stored document's definitions follow the document the app executes, or fall back to first-reach order because that document could not be derived from the tree.
        - `order_reason` 'ambiguous' | 'not_in_tree' | 'underivable'
        - `endpoint` GraphQLEndpointEvidence, required: Where the app's client names its endpoint. Only a string literal gives the path; otherwise the endpoint is named (an env variable, runtime config, a computed value) and its path is assumed.
          - `kind` 'absolute' | 'relative' | 'env' | 'runtime-config' | 'computed' | 'ambiguous' | 'unknown', required: How the app's client names its endpoint: a literal (absolute or relative), an env variable, runtime config, a computed value — or several disagreeing, or none found.
          - `name` string, nullable
          - `path` string, nullable
          - `line` integer, nullable
          - `assumed` boolean, required
        - `schema_repo` string, nullable
        - `schema_paths` string[]
        - `unknown_directives` string[]
    - UploadedSourceRef: Where an action from an API spec file the organization uploaded came from: the file and operation, in an uploaded set of files.
      - `origin` 'uploaded': Always uploaded: read from an uploaded spec file.
      - `repo` 'uploads', required: Always "uploads": the uploaded files, not a repository.
      - `spec_path` string, required: The spec file's path within the upload.
      - `operation_id` string, required: The operation's id within the spec.
      - `set_sha256` string, required: A fingerprint of the whole uploaded set of files the spec was read from.
      - `operation_hash` string, required: A fingerprint of the operation, to notice when the spec changes it.
      - `extractor` integer: The version of the scanner that read the spec.
      - `upload_id` string, required: The id of the upload the spec was read from.
      - `evidence` GraphQLEvidence: How a discovered GraphQL operation was read: the file and line it is written at, whether its stored definition order is the one the app executes, its endpoint, the schema it validated against, and any client-only directives that schema does not declare.
        - `evidence_path` string, required
        - `evidence_line` integer, nullable
        - `document_order` 'executed' | 'first_reach_fallback', required: Whether a stored document's definitions follow the document the app executes, or fall back to first-reach order because that document could not be derived from the tree.
        - `order_reason` 'ambiguous' | 'not_in_tree' | 'underivable'
        - `endpoint` GraphQLEndpointEvidence, required: Where the app's client names its endpoint. Only a string literal gives the path; otherwise the endpoint is named (an env variable, runtime config, a computed value) and its path is assumed.
          - `kind` 'absolute' | 'relative' | 'env' | 'runtime-config' | 'computed' | 'ambiguous' | 'unknown', required: How the app's client names its endpoint: a literal (absolute or relative), an env variable, runtime config, a computed value — or several disagreeing, or none found.
          - `name` string, nullable
          - `path` string, nullable
          - `line` integer, nullable
          - `assumed` boolean, required
        - `schema_repo` string, nullable
        - `schema_paths` string[]
        - `unknown_directives` string[]
  - `graphql` GraphQLOperation, required: One operation of the customer app's own GraphQL client. Its name and type are the action's identity; its document is exactly what their client sends (and a persisted-query allowlist trusts), so it changes only when the app's does — never by hand.
    - `operation_name` string, required: The operation's GraphQL name, like "GetSubscription".
    - `operation_type` 'query' | 'mutation', required: The operation kinds an action can carry; a query defaults like a GET, a mutation like any other write. Subscriptions are refused.
    - `document` string, required: The operation plus every fragment it reaches, in graphql-js print() canonical form.
  - `registered_by_user_id` string, uuid, required: The member who registered it, or who approved the scan's proposal for it.
  - `last_verified_at` string, date-time, nullable, required: When the action was last confirmed to match its spec, by a scan or by approving a scan's proposed change; null until then.
  - `last_verified_commit_sha` string, nullable, required: What that confirmation read: a commit, or for uploaded spec files the fingerprint of the uploaded set (source_ref's set_sha256); null until then.
  - `created_at` string, date-time, required: When the action was registered.
  - `updated_at` string, date-time, required: When the action last changed.
  - `version` integer, required: The action's version; send it back as expected_version so an edit made on a stale screen is refused.
  - `arguments` ActionArgument[], required: The action's top-level arguments — path, query and body parameters, or a GraphQL action's variables — as a member edits them.
    - `section` 'path' | 'query' | 'body' | 'variables', required
    - `name` string, required: The argument's name.
    - `type_label` string, required: What it takes, in words, like "text" or "whole number, or empty".
    - `description` string, nullable, required: What the model reads about it; null when there is none.
    - `required` boolean, required: Whether the model must send it.
    - `required_fixed_reason` string, nullable, required: Why whether it's required can't be changed; null when it can.
    - `allowed_values` unknown[], nullable, required: The only values the model may send; null allows any value.
      - unknown
    - `allowed_value_choices` unknown[], nullable, required: The values the code accepts, to pick allowed values from; null when any value can be entered.
      - unknown
    - `fixed_value` unknown, required
    - `default` unknown, required
    - `nested_fields` string[], required: The names of the fields inside it, which can't be edited here.
    - `edited` EditAspect[], required: What a member changed from what the code says.
    - `editable` boolean, required: Whether it can be edited here.
    - `not_editable_reason` string, nullable, required: Why it can't be edited here; null when it can.
  - `arguments_note` string, nullable, required: Why the request body's fields aren't listed in arguments; null when they are, or there is no body.
  - `member_edited_by_user_id` string, uuid, nullable, required: The member who last edited what the action's code defines; null when no member has since its scan was last approved.
  - `member_edited_at` string, date-time, nullable, required: When a member last edited what the action's code defines; null when no member has since its scan was last approved.

## Other responses

- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not found
- `405`: Method not allowed
- `409`: The slug or the endpoint is already registered
- `422`: Validation error
- `500`: Internal server error

---

[API](https://skmtc.dev/teaflask/apis/teaflask-api.md) - [All operations](https://skmtc.dev/teaflask/apis/teaflask-api/llms.txt) - [OpenAPI document](https://skmtc.dev/teaflask/apis/teaflask-api/revisions/d23e9286b847?raw)
