Call Grace from a hook
Create a project API key and use it in an agent hook, CI script, or local automation.
AI agents can run hooks at different points: before startup, before or after a tool call, or at the end of a task. These scripts are headless — no browser, so an OAuth flow is not possible.
A project API key gives them a way to call Grace tools with a simple
Authorization header.
Create a key
- Open your project → Settings tab → API keys section.
- Choose Create a key, then set:
- a name that states its use ("hook validate — workstation"): it is the only way to identify the key later, because you will not be able to see its value again;
- the tools the key may call — select only what is needed;
- an optional expiration.
- Copy the value immediately. It is shown only once. It is not stored in plain text: nobody, not even a platform administrator, can retrieve it.
You cannot recover a lost key — revoke it and create a new one.
What a key can call
| Tool | Method and route | Purpose in a hook |
|---|---|---|
prepare_task | POST /api/prepare-task | Prepare conventions at the start of a task |
validate | GET /api/validation/playbook | Get the audit playbook before concluding |
record_validation | POST /api/validation/reports | Record verdicts and evidence for reviewed talents |
deepen | GET /api/search and POST /api/talents/get | Find a talent or read its content |
doctor | GET /api/doctor | Diagnose configuration |
catalog | GET /api/catalog | List the catalog |
discover | GET /api/discovery/playbook | Read the discovery procedure |
install | PATCH /api/projects/:id/talents | Changes the talent selection |
install and record_validation write data. A hook that only prepares a task or reads an
audit does not need them. Grant record_validation only to the process that persists
review verdicts, and install only to one that installs or disables talents.
deepen covers both routes of the grace_deepen tool, which routes calls according to its parameters.
After grace_prepare_task, reuse its resolutionId:
{ resolutionId, uris: [{ uri }, …] } reads up to 20 files in one call,
{ resolutionId, uri } reads one, and { resolutionId, query } searches talents.
Group useful addresses in sequential batches of at most 20. This lets Grace connect
preparation, detailed reading, and review without an approximate association.
No other header is necessary: the key identifies its project. If you nevertheless send
x-grace-project, it is ignored — a key cannot be redirected to another project.
Call Grace
curl -s -X POST https://<votre-domaine>/api/prepare-task \
-H "Authorization: Bearer $GRACE_KEY" \
-H "Content-Type: application/json" \
-d '{"talentIds":["grace.architecture.hexagonal"],"language":"typescript"}'Example — end-of-task hook calling validate
Keep the resolutionId returned at the start of the task, then pass it to the playbook:
#!/usr/bin/env bash
set -euo pipefail
: "${GRACE_KEY:?Missing API key}"
: "${GRACE_URL:?Missing Grace URL}"
: "${GRACE_RESOLUTION_ID:?Missing resolutionId}"
# Fetch the playbook even when the working tree is clean: the sealed review may cover committed or untracked changes.
curl -sS --get "$GRACE_URL/api/validation/playbook" \
-H "Authorization: Bearer $GRACE_KEY" \
--data-urlencode "resolutionId=$GRACE_RESOLUTION_ID"The process with the record_validation scope then sends a stable submissionId,
verdicts for reviewable Grace rules, and verdicts for Custom Talents to
POST /api/validation/reports. A key with only validate receives
403 insufficient_scope on this route.
Record the first exhaustive report before correcting a blocking violation. After
correction and a new review, send a second report with a new submissionId. Reuse
the first identifier only to retry the exact same report.
Example — start-of-task hook calling prepare_task
#!/usr/bin/env bash
# Load project conventions into the agent's context before it writes code.
set -euo pipefail
# Get these IDs from the project's designable talent directory
# (GET /api/prepare-task/designable).
talents="${1:?Specify at least one talent, separated by commas}"
curl -sS -X POST "$GRACE_URL/api/prepare-task" \
-H "Authorization: Bearer $GRACE_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg t "$talents" '{ talentIds: ($t | split(",")) }')"Designate everything the work touches and keep the resolutionId from the response: it locks in
the talents and private versions served, which are exactly what the audit playbook covers.
Anything not designated is neither served nor reviewed.
Where to put the key
In an environment variable, never in a committed file. The grc_pk_ prefix is
distinctive: it lets a secret scanner (gitleaks, trufflehog) spot a leak.
- Development workstation: your shell profile or the agent's secrets manager.
- CI: repository or organization secrets.
Understand denied requests
| Response | What happens |
|---|---|
401 invalid_token | Unknown, revoked, or expired key — or disabled feature. The response is deliberately the same in all four cases. |
403 insufficient_scope | The key is not authorized for this tool. requiredScope identifies the scope needed; create a new key with that scope selected. |
403 (organization) | The project's organization is no longer approved. |
403 not_a_member | The key's owner is no longer a member of the organization. |
404 | The project no longer exists. |
Permissions are re-evaluated on every call: a key does not lock them in. If you leave the organization, your keys stop working; if you rejoin, they work again.
Revoke a key
In the same section, choose Revoke. It takes effect immediately: the next call is denied.
Any project member can see and revoke project keys, including those created by someone else. A key used in a hook or CI is part of the project's operations, not a personal secret — and if it leaks, revocation must not wait for its creator to return.
What keys cannot do
- Manage other keys: creation and revocation require a web session. A leaked key cannot perpetuate itself.
- Access the dashboard: a key opens only its named tools on its project.
- Replace OAuth for interactive use: to connect an agent to Grace, use the project's MCP URL, which contains no secret and can be committed.