---
title: "Update"
method: POST
path: "/api/v1/funds/policy/update"
tags: ["Fund Policy"]
---

# Update

`POST /api/v1/funds/policy/update`

Update the period or the default limit. currency_code is immutable after
 Create and update_mask rejects it: an amount denominated in a currency the
 policy no longer names faults the acquire path rather than denying it.

## Request body

- C1ApiFundsV1FundPolicyServiceUpdateRequest — The FundPolicyServiceUpdateRequest message.
  - `policy` C1ApiFundsV1FundPolicy — FundPolicy is the tenant's fund policy as the API renders it. Every field is server-owned on the way out; requests name the fields they change rather than sending this message back.
    - `createdAt` string, date-time, nullable
    - `currencyCode` string — ISO 4217. Set at Create and immutable thereafter.
    - `defaultLimit` C1ModelsFundsV1SpendLimit — SpendLimit is the three-way behavior fork. Which arms are legal depends on the scope carrying it; pkg/funds enforces that matrix, not the schema, because one SpendControls shape is shared by every scope. This message contains a oneof named kind. Only a single field of the following list may be set at a time: - unlimited - amount - blocked
      - `amount` C1ModelsFundsV1SpendLimitAmount — SpendLimitAmount caps spend at money per resolved period.
        - `money` C1ModelsFundsV1Money — Money is wire-compatible with google.type.Money field-for-field, so the public API converts with a field copy. Declared here rather than imported because protoc-gen-pgdb mirrors a nested message by calling its generated DBReflect, which only exists for messages this repo generates.
          - `currencyCode` string — ISO 4217 currency code. Must equal the tenant's FundPolicy.currency_code.
          - `nanos` integer — Nano-unit remainder, 0 <= nanos < 10^9. Non-negative for the same reason as units, which also keeps the (units, nanos) pair unambiguous.
          - `units` string, int64 — Non-negative — grants, never debts — and bounded so units * 10^9 + nanos always fits int64. Without the ceiling a large value wraps positive and installs a limit nobody granted. The pair check spans two fields, so pkg/funds re-checks it on every conversion.
      - `blocked` C1ModelsFundsV1SpendLimitBlocked — SpendLimitBlocked refuses supply at this scope. Distinct from suspension: blocked is a stated policy posture, suspension is a reversible freeze that preserves the numbers underneath it.
      - `unlimited` C1ModelsFundsV1SpendLimitUnlimited — SpendLimitUnlimited is a tracking limit: full accounting, no admission condition. The maximum element, so an unlimited default makes grant rules no-ops.
    - `orgCeiling` C1ModelsFundsV1SpendControls — SpendControls is the one control shape carried by every authority scope. Per-row resolution, identical everywhere: suspension present -> deny; unexpired extension -> extension.limit; limit present -> limit; otherwise this row states no opinion and resolution falls through. Not a oneof: two transitions need the losing field to survive. Unsuspending restores the limit it froze, and a lapsed extension falls back to its base rather than to the next layer. Pinned by TestControlsCoPresenceSurvivesEveryTransition in pkg/funds.
      - `extension` C1ModelsFundsV1SpendExtension — SpendExtension replaces the row's total with a temporary one until expires_at. It never changes the period, and it never expresses a refusal — a temporary refusal is a SpendSuspension.
        - `expiresAt` string, date-time, nullable
        - `limit` C1ModelsFundsV1SpendLimit — SpendLimit is the three-way behavior fork. Which arms are legal depends on the scope carrying it; pkg/funds enforces that matrix, not the schema, because one SpendControls shape is shared by every scope. This message contains a oneof named kind. Only a single field of the following list may be set at a time: - unlimited - amount - blocked
          - `amount` C1ModelsFundsV1SpendLimitAmount — SpendLimitAmount caps spend at money per resolved period.
            - `money` C1ModelsFundsV1Money — Money is wire-compatible with google.type.Money field-for-field, so the public API converts with a field copy. Declared here rather than imported because protoc-gen-pgdb mirrors a nested message by calling its generated DBReflect, which only exists for messages this repo generates.
              - …
          - `blocked` C1ModelsFundsV1SpendLimitBlocked — SpendLimitBlocked refuses supply at this scope. Distinct from suspension: blocked is a stated policy posture, suspension is a reversible freeze that preserves the numbers underneath it.
          - `unlimited` C1ModelsFundsV1SpendLimitUnlimited — SpendLimitUnlimited is a tracking limit: full accounting, no admission condition. The maximum element, so an unlimited default makes grant rules no-ops.
        - `reason` string — Subject-visible: "why do I have this bump". Mutation rationale rides the history change_reason annotation instead.
      - `limit` C1ModelsFundsV1SpendLimit — SpendLimit is the three-way behavior fork. Which arms are legal depends on the scope carrying it; pkg/funds enforces that matrix, not the schema, because one SpendControls shape is shared by every scope. This message contains a oneof named kind. Only a single field of the following list may be set at a time: - unlimited - amount - blocked
        - `amount` C1ModelsFundsV1SpendLimitAmount — SpendLimitAmount caps spend at money per resolved period.
          - `money` C1ModelsFundsV1Money — Money is wire-compatible with google.type.Money field-for-field, so the public API converts with a field copy. Declared here rather than imported because protoc-gen-pgdb mirrors a nested message by calling its generated DBReflect, which only exists for messages this repo generates.
            - `currencyCode` string — ISO 4217 currency code. Must equal the tenant's FundPolicy.currency_code.
            - `nanos` integer — Nano-unit remainder, 0 <= nanos < 10^9. Non-negative for the same reason as units, which also keeps the (units, nanos) pair unambiguous.
            - `units` string, int64 — Non-negative — grants, never debts — and bounded so units * 10^9 + nanos always fits int64. Without the ceiling a large value wraps positive and installs a limit nobody granted. The pair check spans two fields, so pkg/funds re-checks it on every conversion.
        - `blocked` C1ModelsFundsV1SpendLimitBlocked — SpendLimitBlocked refuses supply at this scope. Distinct from suspension: blocked is a stated policy posture, suspension is a reversible freeze that preserves the numbers underneath it.
        - `unlimited` C1ModelsFundsV1SpendLimitUnlimited — SpendLimitUnlimited is a tracking limit: full accounting, no admission condition. The maximum element, so an unlimited default makes grant rules no-ops.
      - `period` 'PERIOD_KIND_UNSPECIFIED' | 'PERIOD_KIND_DAILY' | 'PERIOD_KIND_WEEKLY' | 'PERIOD_KIND_MONTHLY' | 'PERIOD_KIND_QUARTERLY' | 'PERIOD_KIND_YEARLY' — Only valid together with limit: a period without its amount would reinterpret some other layer's number in a cadence that layer never agreed to.
      - `suspension` C1ModelsFundsV1SpendSuspension — SpendSuspension freezes a scope without erasing the limit it must restore on unsuspend, which is why it lives beside the SpendLimit oneof rather than inside it.
        - `reason` string — The reason field.
        - `suspendedAt` string, date-time, nullable
    - `period` 'PERIOD_KIND_UNSPECIFIED' | 'PERIOD_KIND_DAILY' | 'PERIOD_KIND_WEEKLY' | 'PERIOD_KIND_MONTHLY' | 'PERIOD_KIND_QUARTERLY' | 'PERIOD_KIND_YEARLY' — The root period every amount in the tenant is denominated in.
    - `tenantId` string — The tenantId field.
    - `updatedAt` string, date-time, nullable
  - `updateMask` string, nullable

## Response `200`

Successful response

- C1ApiFundsV1FundPolicyServiceUpdateResponse — The FundPolicyServiceUpdateResponse message.
  - `policy` C1ApiFundsV1FundPolicy — FundPolicy is the tenant's fund policy as the API renders it. Every field is server-owned on the way out; requests name the fields they change rather than sending this message back.
    - `createdAt` string, date-time, nullable
    - `currencyCode` string — ISO 4217. Set at Create and immutable thereafter.
    - `defaultLimit` C1ModelsFundsV1SpendLimit — SpendLimit is the three-way behavior fork. Which arms are legal depends on the scope carrying it; pkg/funds enforces that matrix, not the schema, because one SpendControls shape is shared by every scope. This message contains a oneof named kind. Only a single field of the following list may be set at a time: - unlimited - amount - blocked
      - `amount` C1ModelsFundsV1SpendLimitAmount — SpendLimitAmount caps spend at money per resolved period.
        - `money` C1ModelsFundsV1Money — Money is wire-compatible with google.type.Money field-for-field, so the public API converts with a field copy. Declared here rather than imported because protoc-gen-pgdb mirrors a nested message by calling its generated DBReflect, which only exists for messages this repo generates.
          - `currencyCode` string — ISO 4217 currency code. Must equal the tenant's FundPolicy.currency_code.
          - `nanos` integer — Nano-unit remainder, 0 <= nanos < 10^9. Non-negative for the same reason as units, which also keeps the (units, nanos) pair unambiguous.
          - `units` string, int64 — Non-negative — grants, never debts — and bounded so units * 10^9 + nanos always fits int64. Without the ceiling a large value wraps positive and installs a limit nobody granted. The pair check spans two fields, so pkg/funds re-checks it on every conversion.
      - `blocked` C1ModelsFundsV1SpendLimitBlocked — SpendLimitBlocked refuses supply at this scope. Distinct from suspension: blocked is a stated policy posture, suspension is a reversible freeze that preserves the numbers underneath it.
      - `unlimited` C1ModelsFundsV1SpendLimitUnlimited — SpendLimitUnlimited is a tracking limit: full accounting, no admission condition. The maximum element, so an unlimited default makes grant rules no-ops.
    - `orgCeiling` C1ModelsFundsV1SpendControls — SpendControls is the one control shape carried by every authority scope. Per-row resolution, identical everywhere: suspension present -> deny; unexpired extension -> extension.limit; limit present -> limit; otherwise this row states no opinion and resolution falls through. Not a oneof: two transitions need the losing field to survive. Unsuspending restores the limit it froze, and a lapsed extension falls back to its base rather than to the next layer. Pinned by TestControlsCoPresenceSurvivesEveryTransition in pkg/funds.
      - `extension` C1ModelsFundsV1SpendExtension — SpendExtension replaces the row's total with a temporary one until expires_at. It never changes the period, and it never expresses a refusal — a temporary refusal is a SpendSuspension.
        - `expiresAt` string, date-time, nullable
        - `limit` C1ModelsFundsV1SpendLimit — SpendLimit is the three-way behavior fork. Which arms are legal depends on the scope carrying it; pkg/funds enforces that matrix, not the schema, because one SpendControls shape is shared by every scope. This message contains a oneof named kind. Only a single field of the following list may be set at a time: - unlimited - amount - blocked
          - `amount` C1ModelsFundsV1SpendLimitAmount — SpendLimitAmount caps spend at money per resolved period.
            - `money` C1ModelsFundsV1Money — Money is wire-compatible with google.type.Money field-for-field, so the public API converts with a field copy. Declared here rather than imported because protoc-gen-pgdb mirrors a nested message by calling its generated DBReflect, which only exists for messages this repo generates.
              - …
          - `blocked` C1ModelsFundsV1SpendLimitBlocked — SpendLimitBlocked refuses supply at this scope. Distinct from suspension: blocked is a stated policy posture, suspension is a reversible freeze that preserves the numbers underneath it.
          - `unlimited` C1ModelsFundsV1SpendLimitUnlimited — SpendLimitUnlimited is a tracking limit: full accounting, no admission condition. The maximum element, so an unlimited default makes grant rules no-ops.
        - `reason` string — Subject-visible: "why do I have this bump". Mutation rationale rides the history change_reason annotation instead.
      - `limit` C1ModelsFundsV1SpendLimit — SpendLimit is the three-way behavior fork. Which arms are legal depends on the scope carrying it; pkg/funds enforces that matrix, not the schema, because one SpendControls shape is shared by every scope. This message contains a oneof named kind. Only a single field of the following list may be set at a time: - unlimited - amount - blocked
        - `amount` C1ModelsFundsV1SpendLimitAmount — SpendLimitAmount caps spend at money per resolved period.
          - `money` C1ModelsFundsV1Money — Money is wire-compatible with google.type.Money field-for-field, so the public API converts with a field copy. Declared here rather than imported because protoc-gen-pgdb mirrors a nested message by calling its generated DBReflect, which only exists for messages this repo generates.
            - `currencyCode` string — ISO 4217 currency code. Must equal the tenant's FundPolicy.currency_code.
            - `nanos` integer — Nano-unit remainder, 0 <= nanos < 10^9. Non-negative for the same reason as units, which also keeps the (units, nanos) pair unambiguous.
            - `units` string, int64 — Non-negative — grants, never debts — and bounded so units * 10^9 + nanos always fits int64. Without the ceiling a large value wraps positive and installs a limit nobody granted. The pair check spans two fields, so pkg/funds re-checks it on every conversion.
        - `blocked` C1ModelsFundsV1SpendLimitBlocked — SpendLimitBlocked refuses supply at this scope. Distinct from suspension: blocked is a stated policy posture, suspension is a reversible freeze that preserves the numbers underneath it.
        - `unlimited` C1ModelsFundsV1SpendLimitUnlimited — SpendLimitUnlimited is a tracking limit: full accounting, no admission condition. The maximum element, so an unlimited default makes grant rules no-ops.
      - `period` 'PERIOD_KIND_UNSPECIFIED' | 'PERIOD_KIND_DAILY' | 'PERIOD_KIND_WEEKLY' | 'PERIOD_KIND_MONTHLY' | 'PERIOD_KIND_QUARTERLY' | 'PERIOD_KIND_YEARLY' — Only valid together with limit: a period without its amount would reinterpret some other layer's number in a cadence that layer never agreed to.
      - `suspension` C1ModelsFundsV1SpendSuspension — SpendSuspension freezes a scope without erasing the limit it must restore on unsuspend, which is why it lives beside the SpendLimit oneof rather than inside it.
        - `reason` string — The reason field.
        - `suspendedAt` string, date-time, nullable
    - `period` 'PERIOD_KIND_UNSPECIFIED' | 'PERIOD_KIND_DAILY' | 'PERIOD_KIND_WEEKLY' | 'PERIOD_KIND_MONTHLY' | 'PERIOD_KIND_QUARTERLY' | 'PERIOD_KIND_YEARLY' — The root period every amount in the tenant is denominated in.
    - `tenantId` string — The tenantId field.
    - `updatedAt` string, date-time, nullable

## Changes

- **2026-09-01** `f76d07868c0c` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/conductorone/apis/c1-api/changes/api/v1/funds/policy/update/post.md)

---

[API](https://skmtc.dev/conductorone/apis/c1-api.md) · [All operations](https://skmtc.dev/conductorone/apis/c1-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/conductorone/c1-api/revisions/f76d07868c0c/schema)
