# What a route runs

`run:` calls one named action. It passes the placeholders, `input` and the
caller as ordinary arguments. A `GET` calls a named query instead, so it
can never write, as HTTP promises of a `GET`, and a read needs no action
wrapped around its query:

```jadpo
GET /{todo_id: Todo.id} {
    output: TodoView
    run: todo_view(todo_id)
}

POST /{todo_id: Todo.id}/complete {
    output: TodoView
    run: complete_todo(todo_id)
}
```

The query `todo_view` lives in its domain's `queries/` folder, and the
action `complete_todo` in `actions/`. Your own domain's actions and queries
are called by their names. Another domain's `public` ones are called
through that domain's name, as in `billing.charge(order)`
([Project layout and modules](project-layout-and-modules.md)). A route
can't hold an action of its own written inline.

## Listing tokens and keys

A `GET` can also run the listings Jadpo generates for sign-in credentials.
`sessions.tokens(user_id)` lists the tokens a user holds, and
`<Service>.keys(service_id)` the keys a service holds
([Service credentials](service-credentials.md)). They read the
tokens and keys the runtime keeps, so a route lists them without an action
that copies each one into an `Output`.

The route passes the holder's `id`, from a placeholder or from
`current_principal`. Its `output:` is the `List<IssuedToken>` or
`List<IssuedKey>` the listing returns, exactly as for a named query:

```jadpo
GET /devices {
    output: List<IssuedToken>
    run: sessions.tokens(current_principal.user.id)
}
```
