---
title: "Deny a queued IC Credits request"
method: POST
path: "/api/credits/admin/deny"
tags: ["keys"]
---

# Deny a queued IC Credits request

`POST /api/credits/admin/deny`

## Request

- Base URL: `https://www.immersivecommons.com`
- URL: `https://www.immersivecommons.com/api/credits/admin/deny`
- Auth: one of:
  - API key in cookie `__session`
  - HTTP bearer

Clerk operator session OR an agt_ token carrying `admin:llm_keys`, live tier re-checked. TWO-STEP like its approve sibling: without `confirm` it previews and charges nothing. No key is ever minted. Refuses an ALREADY-APPROVED request (409); revoke the minted key at /api/credits/admin/revoke instead. Idempotent on an already-denied one (`was_pending: false`).

## Request body

- ZaiKeyDenyRequest
  - `request_id` string, required: The pending request to deny.
  - `reason` string: Free text for the audit trail; trimmed to 400 characters.
  - `confirm` boolean: Omit or false for a dry-run preview; true denies. Default false.

## Response `200`

The dry-run preview, or the denied record.

- ZaiKeyDenyResponse
  - `ok` boolean, required
  - `dry_run` boolean: True on the preview call.
  - `request_id` string
  - `action` string: The verb the preview describes — deny.
  - `was_pending` boolean: False when the request had already been denied.
  - `message` string: Human-readable note on the preview.

## Other responses

- `400`: Invalid JSON or missing request_id.
- `401`: No auth.
- `403`: Not an operator / scope not authorized.
- `404`: No such request.
- `409`: Already approved; deny is no longer the right verb.
- `429`: Per-actor daily review cap reached; only a confirmed deny charges it.

---

[API](https://skmtc.dev/immersivecommons/apis/immersive-commons-agent-rest-api.md) · [All operations](https://skmtc.dev/immersivecommons/apis/immersive-commons-agent-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/immersivecommons/apis/immersive-commons-agent-rest-api/revisions/be67c1f67c27?raw)
