---
title: "Internal Approve Accounts"
method: POST
path: "/api/v1/admin/block/requests/{request_id}/internal-approve/accounts"
tags: ["Admin APIs", "block-data-approvals"]
---

# Internal Approve Accounts

`POST /api/v1/admin/block/requests/{request_id}/internal-approve/accounts`

Approve at the Accounts internal step.

Body is optional — bare approval keeps the captured-at-creation
trial duration and annual price. Pass ``trial_duration_months``
and/or ``annual_price`` with a ``custom_adjustment_rationale``
to apply a custom adjustment before the queue advances to Legal.

An ``annual_price`` above the catalog list price additionally requires
``above_list_acknowledged`` — 400 ``above_list_price`` otherwise, carrying
both figures so the UI can render a confirmation.

``s3_grant`` awards S3 tokens for the contract this request will become. The
contract does not exist yet — the trial has not even started — so the award is
held ``awaiting_contract`` and its vesting schedule is built when the
subscription webhook lands, which is what lines each vest up with the invoice
it funds. A Historic (``one_time``) request is refused with 400
``s3_grant_rejected``: its only invoice is raised before anything vests.

## Path parameters

- `request_id` string, uuid, required

## Request body

- BlockAccountsApprovalBody — Body for ``POST /block/requests/{id}/internal-approve/accounts``. All three fields optional — a bare approval (no body, or empty body) accepts the captured-at-creation trial duration + annual price. Supplying ``trial_duration_months`` OR ``annual_price`` (to override the catalog/dataset snapshot) requires ``custom_adjustment_rationale`` so the adjustment lands with a CarbonArc-authored audit string. 0 is a valid trial value and bypasses the trial/intake phases entirely (provisioning success transitions straight to ``contracted``). ``annual_price`` must be positive: free access is expressed with ``trial_duration_months``, not a $0 twelve-month contract, so a 0 here is a fat-finger that would open a $0 Stripe subscription. An override ABOVE the catalog list price additionally requires ``above_list_acknowledged``. Finance leaves list as list and promotes against it, so below-list is a discount while above-list is the exceptional path that mints a bespoke Price — worth making deliberate.
  - `trial_duration_months` integer, nullable
  - `annual_price` union
    - number
    - string
  - `custom_adjustment_rationale` string, nullable
  - `above_list_acknowledged` boolean, nullable
  - `s3_grant` BlockAccountsS3Grant — An S3 token award made at the Accounts approval step. **Independent of the custom adjustment.** Awarding tokens is not a change to the trial or the price, so it does not require ``custom_adjustment_rationale`` and does not count as one of the adjustments that rationale explains. It was originally folded in, which forced an operator who only wanted to award tokens to invent a trial or price change to unlock the field, and then to justify a change they had not made. It carries its own ``reason`` instead: the grant row has a NOT NULL ``reason`` that CAMS renders on the Vesting Schedule, and "why does this client have 12,000 tokens" and "why did we shorten their trial" are different questions with different answers. No ``vesting_kind``: an award tied to a contract always vests over the 12 billing periods, because that is what makes each month's vest land on the invoice it funds. Offering ``immediate`` here would only allow the one shape that cannot line up.
    - `amount` union, required
      - number
      - string
    - `order_id` string, required
    - `reason` string, required
    - `auto_apply` boolean

## Response `200`

Successful Response

- BlockRequestRead
  - `id` string, uuid, required
  - `dataset_id` string, required
  - `lag` string, nullable
  - `cut` string, nullable
  - `label` string, nullable
  - `internal_name` string, nullable
  - `core_source` string, nullable
  - `client_id` string, uuid, required
  - `client_polaris_principal_missing` boolean
  - `client_name` string, nullable
  - `requestor_email` string, required
  - `status` 'pending_block_admin' | 'pending_compliance' | 'pending_internal' | 'approved' | 'intake_pending' | 'provisioning' | 'provisioning_failed' | 'trial_pending' | 'trial_active' | 'contracted' | 'contract_expired' | 'request_cancelled' | 'trial_cancelled' | 'contract_cancelled' | 'block_cancelled' | 'rejected', required
  - `internal_queue_step` 'accounts' | 'legal' | 'engineering' | 'complete'
  - `rejection_source` 'client_block_admin' | 'client_compliance' | 'carbonarc_accounts' | 'carbonarc_legal' | 'carbonarc_engineering'
  - `rejection_message` string, nullable
  - `rejected_by` string, nullable
  - `fee_type` 'one_time' | 'annual', required
  - `trial_duration_months` integer, required
  - `annual_price` string, nullable
  - `original_trial_duration_months` integer, nullable
  - `original_annual_price` string, nullable
  - `custom_adjustment_rationale` string, nullable
  - `additional_email_recipients` string[]
  - `use_case` string, nullable
  - `trial_start_date` string, date-time, nullable
  - `trial_end_date` string, date-time, nullable
  - `original_trial_start_date` string, date-time, nullable
  - `original_trial_end_date` string, date-time, nullable
  - `first_ingestion_at` string, date-time, nullable
  - `trial_start_trigger` 'first_ingestion' | 'auto_start'
  - `approved_by_block_admin` string, nullable
  - `approved_by_compliance` string, nullable
  - `approved_at` string, date-time, nullable
  - `cancellation_requested_at` string, date-time, nullable
  - `cancellation_requested_by` string, nullable
  - `cancellation_request_reason` string, nullable
  - `compliance_tear_sheet` BlockComplianceTearSheetMeta — Per-dataset compliance tear sheet metadata. Mirrors the ``ComplianceTearSheetMeta`` TypedDict in ``app.services.compliance_tear_sheet`` so the same dict shape can be model_validate'd onto a pydantic schema.
    - `available` boolean, required
    - `size_bytes` integer, nullable
    - `updated_at` string, date-time, nullable
    - `download_url` string, nullable
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/carbonarc/apis/carbon-arc-client-admin-api.md) · [All operations](https://skmtc.net/carbonarc/apis/carbon-arc-client-admin-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/carbonarc/carbon-arc-client-admin-api/revisions/a8ca30023371/schema)
