---
title: Projects and scoping
description: How the calling key's home project, and the optional project argument, decide what a call can reach.
---

# Projects and scoping

Every key belongs to exactly one **home project**, and reaches it in
full — no `project` argument needed for normal use.

## Reaching a different project

Pass `project` (a slug) to reach somewhere else:

- A **master** key can name any of the account's other projects.
- An **app** key can only reach a project it's been explicitly granted
  `read` or `full` access to, via `project_grant_key`.

Naming a project the key can't reach fails as `insufficient_scope`
(`403`) — never a not-found error, so a key can't learn whether a
project it can't see even exists.

## Grants are per project, not global

`project_grant_key({ key_id, project, level })` grants one key access to
one other project, at `read` (list/view) or `full` (create/update/
delete) level. `project_revoke_grant` undoes it. A grant on one project
says nothing about any other.

## Calls don't remember what you passed last

Each call is scoped independently. Publishing a page with
`project: "acme"` and then calling `link_list` with no `project` still
returns your key's home project's links, not `acme`'s — pass
`project: "acme"` again on that call too.

## Home project vs. account default

A brand-new account's one project (named `default`) happens to also be
every early key's home project — but a project created later can be a
key's home project too, if you bind it there at mint time
(`key_create_app`'s own `project` argument). "Home project" and "the
account's default project" are related, but not the same thing, once an
account has more than one project.

## Next

[Keys](/concepts/keys) — how a key's tier decides more than which
project it can reach.
