# The @deploy decorator

> Every option @deploy takes: name, title, description, secrets, timeout, schedule and next.

Source: https://callables.app/docs/deploy

`@deploy` marks a function as something your team can run. It works bare or with options:

```python
from callables import deploy


@deploy
def ping() -> str:
    return "pong"


@deploy(
    title="Closed deals",
    secrets=["CRM_TOKEN"],
    timeout=120,
)
def closed_deals(region: str = "NA", min_value: int = 0) -> list[dict]:
    """Deals closed in a region, newest first.

    Pulls from the CRM; amounts are in USD.
    """
    ...
```

The person running a function can't see its code. Everything they see comes from the decorator, the docstring, the parameter names and types, and the return value, so write those for them.

## Options

| Option | Default | What it does |
|---|---|---|
| `name` | the function's name | The function's identity on the platform |
| `title` | the name as a sentence | The heading on its card and page |
| `description` | the docstring's first paragraph | One line about what it does |
| `secrets` | none | Environment variables injected at run time |
| `timeout` | `300` | Seconds before the run is stopped, up to `900` |
| `schedule` | none | A cron expression in UTC, for a schedule kept in code |
| `next` | none | Actions offered on each result row |

## name

The function's identity. Run history, sharing and schedules belong to it. **Changing the name creates a new function**, and the old one's history and schedules stay behind. If you rename the Python function, pass the old name to keep its identity:

```python
@deploy(name="closed_deals")
def deals_closed_by_region(region: str = "NA") -> list[dict]: ...
```

Inside a [group](https://callables.app/docs/groups), the full name is `<group>.<name>`, such as `billing.refund`.

## title and description

`title` defaults to the name with underscores as spaces, so `closed_deals` shows as "Closed deals". `description` defaults to the first paragraph of the docstring. Write one plain sentence about what the function does for the person running it, not how it works.

## secrets

A list of environment variable names. Builders set the values in the web app, and they're injected when the function runs. Read them inside the function:

```python
import os

token = os.environ["CRM_TOKEN"]
```

A declared secret that nobody has set doesn't block the run. The variable is simply missing, and builders see a "missing secrets" warning. See [secrets](https://callables.app/docs/secrets).

## timeout

Seconds before the run is stopped. The default is 300 (5 minutes) and the maximum is 900 (15 minutes). A higher value is capped at 900, and `call check` warns about it.

## schedule

A cron expression in UTC, such as `"0 9 * * MON"`. The schedule is created on push and removed when you delete the line. Every input needs a default. You usually don't need this: anyone can add a schedule in the web app, with a time zone. See [schedules](https://callables.app/docs/schedules).

## next

Actions offered on each row of the result, with their inputs filled in from the row. See [flows](https://callables.app/docs/flows).

## Errors

Raise exceptions with messages written for the person running the function. They see the message, such as `ValueError: No deals found for EMEA since 2026-01-01`, but never the traceback. For bad input, raise `ValueError` and say which field to change. Builders see the full traceback on the run page.
