Skip to main content

Declaring actions

An action is a hook that declares an api_schema in abstra.json. Other projects can only call hooks that declare one, and the schema is what they see and are validated against.

{
"hooks": [
{
"id": "930efb6d-f985-4f80-89f6-3f9efa52a539",
"path": "quote-order",
"title": "Quote Order",
"file": "quote_order.py",
"api_schema": {
"description": "Prices an order. Computes a quote only; nothing is stored.",
"input": {
"type": "object",
"properties": {
"customer": {
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string" }
},
"required": ["name", "email"]
},
"items": {
"type": "array",
"minItems": 1,
"items": { "$ref": "#/$defs/lineItem" }
}
},
"required": ["customer", "items"],
"additionalProperties": false,
"$defs": {
"lineItem": {
"type": "object",
"properties": {
"sku": { "type": "string", "pattern": "^[A-Z]{3}-[0-9]{3}$" },
"quantity": { "type": "integer", "minimum": 1 }
},
"required": ["sku", "quantity"]
}
}
},
"output": {
"type": "object",
"properties": { "total": { "type": "number" } }
}
}
}
]
}
FieldRequiredDescription
descriptionnoWhat the action does. Shown to callers and AI agents.
inputyesJSON Schema (2020-12) of the parameters, with "type": "object". Use $defs and "$ref": "#/$defs/..." for reusable parts.
outputnoJSON Schema of what the hook answers. Shown to callers; not enforced.
  • The action's name comes from the hook's path (quote-order above): characters other than letters, digits, - and _ become _.
  • Parameters are validated before the hook runs. A call that doesn't match gets every error back, with its path, and the hook never runs.
  • "additionalProperties": false rejects parameters the hook doesn't expect, which catches typos early.
  • Changes to api_schema take effect when you deploy.
Adding a schema

You can edit abstra.json directly, or ask Smart Chat to "add an api_schema to the Quote Order hook" with the parameters it takes.

Writing the hook​

The parameters arrive as the request's JSON body:

import abstra.hooks as ah

order, query, headers = ah.get_request()
total = sum(item["quantity"] * price_of(item["sku"]) for item in order["items"])
ah.send_json({"total": total})
  • Answer with send_json for structured results: callers get it parsed.
  • Answer with an error status (for example ah.send_json({"error": "Unknown coupon"}, status_code=422)) to make run_app_action raise AppActionError with that status and your body in details.
  • The same hook can still be called over HTTP at its URL. Those requests skip the schema validation, so keep validating what your code relies on.

Who can call it​

Declaring a schema doesn't change who can run the hook:

  • A public hook can be called by any project, as it can be called by anyone over HTTP.
  • A private hook can be called by the projects holding one of its roles. See Giving a project access.