Orgs
Generated HTTP reference for the 15 operations the published OpenAPI document describes under orgs.
Orgs
This page is generated from the published OpenAPI document. It is complete with respect to that document and says nothing about surfaces the document does not describe yet. See what is generated here for what that means.
Base URL: https://api.codespar.dev
Every operation below requires a Bearer token. See Authentication.
POST /v1/orgs/{orgId}/agents
Register an agent identity and mint its first signing key
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
orgId | string | yes | — |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | yes | — |
display_name | string | no | — |
principal_ref | string | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
201 | object | OK |
400 | object | The body failed the schema (details.issues carries the Zod issues), or the org or the handle contains characters a did:web cannot hold. |
403 | object | The \{orgId\} in the path is not the authenticated org. |
409 | object | The agent already has an active key, or the derived did:web belongs to another org. |
Response 201
| Field | Type | Required | Description |
|---|---|---|---|
agent_did | string | yes | did:web: derived from the org and the handle. |
kid | string | yes | \<agent_did\>#\<n\>. |
pubkey | string | yes | Raw 32-byte Ed25519 public key, base64. |
status | "active" | yes | — |
Example response
{
"agent_did": "did:web:codespar.dev:org:agent",
"kid": "string",
"pubkey": "string",
"status": "active"
}Example request
curl -X POST https://api.codespar.dev/v1/orgs/{orgId}/agents \
-H "Authorization: Bearer $CODESPAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "agt_0000000000000000",
"display_name": "Example",
"principal_ref": "string"
}'POST /v1/orgs/{orgId}/agents/{agentId}/keys/rotate
Retire the agent's active key and mint a fresh one
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
agentId | string | yes | The registration handle, not the did:web. |
orgId | string | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
201 | object | OK |
403 | object | The \{orgId\} in the path is not the authenticated org. |
404 | object | No agent with that handle in this org. |
409 | object | The agent holds no active key to rotate. |
Response 201
| Field | Type | Required | Description |
|---|---|---|---|
agent_did | string | yes | — |
kid | string | yes | The new active key. |
pubkey | string | yes | Raw 32-byte Ed25519 public key, base64. |
retired_kid | string | yes | The key just retired. It still verifies what it signed before retirement; it can only no longer sign anything new. |
status | "active" | yes | — |
Example response
{
"agent_did": "did:web:codespar.dev:org:agent",
"kid": "string",
"pubkey": "string",
"retired_kid": "string",
"status": "active"
}Example request
curl -X POST https://api.codespar.dev/v1/orgs/{orgId}/agents/{agentId}/keys/rotate \
-H "Authorization: Bearer $CODESPAR_API_KEY"POST /v1/orgs/{orgId}/agents/{agentId}/keys/{kid}/revoke
Hard-revoke one of an agent's signing keys
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
agentId | string | yes | The registration handle, not the did:web. |
kid | string | yes | \<did:web:...\>#\<n\>, with the # percent-encoded as %23. |
orgId | string | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
403 | object | The \{orgId\} in the path is not the authenticated org. |
404 | object | No such key for that agent in this org. |
409 | object | That key is already revoked. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
kid | string | yes | — |
revoked_at | string (date-time) | yes | — |
status | "revoked" | yes | — |
Example response
{
"kid": "string",
"status": "revoked",
"revoked_at": "2026-01-15T12:00:00.000Z"
}Example request
curl -X POST https://api.codespar.dev/v1/orgs/{orgId}/agents/{agentId}/keys/{kid}/revoke \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/orgs/{orgId}/approvals/health
Queue depth and the age of the oldest pending approval
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
orgId | string | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
404 | object | Not Found |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
last_sweep_at | string,null (date-time) | yes | Deployment-wide, not scoped to this org. |
oldest_pending_age_seconds | integer,null | yes | Null when nothing is pending. Rounded to whole seconds. |
pending_count | integer | yes | — |
status | "ok" | yes | — |
Example response
{
"status": "ok",
"pending_count": 1
}Example request
curl -X GET https://api.codespar.dev/v1/orgs/{orgId}/approvals/health \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/orgs/{orgId}/approvals/{id}
Read one approval, including the tool arguments held for review
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | — |
orgId | string | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
404 | object | Not Found |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | yes | — |
created_at | string (date-time) | yes | — |
decided_at | string,null (date-time) | yes | — |
decided_by | string,null | yes | — |
decision_reason | string,null | yes | — |
executed_at | string,null (date-time) | yes | — |
execution_result | object,null | yes | — |
expires_at | string (date-time) | yes | — |
id | string | yes | — |
matched_rule_id | string | yes | — |
matched_rule_name | string | yes | — |
org_id | string | yes | — |
project_id | string,null | yes | — |
session_id | string,null | yes | — |
status | "pending" | "approved" | "denied" | "expired" | "execution_failed" | yes | Closed by the table's own CHECK constraint, not by convention. |
tool_input | object | yes | The tool arguments the rule held for review, verbatim. |
tool_name | string | yes | — |
Example response
{
"id": "obj_0000000000000000",
"org_id": "org_0000000000000000",
"agent_id": "agt_0000000000000000",
"matched_rule_id": "matchedrule_0000000000000000",
"matched_rule_name": "Example",
"tool_name": "Example",
"tool_input": {},
"status": "pending",
"created_at": "2026-01-15T12:00:00.000Z",
"expires_at": "2026-01-15T12:00:00.000Z"
}Example request
curl -X GET https://api.codespar.dev/v1/orgs/{orgId}/approvals/{id} \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/orgs/{orgId}/audit/config
Read the chain verification windows and staleness budgets
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
orgId | string | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
403 | object | The \{orgId\} in the path is not the authenticated org. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
cold_max_staleness_seconds | integer | yes | — |
created_at | string (date-time) | yes | — |
hot_max_staleness_seconds | integer | yes | — |
hot_window_days | integer | yes | — |
initial_walk_completed_at | string,null (date-time) | yes | Null until the first forward walk has reached the chain tip. |
org_id | string | yes | — |
updated_at | string (date-time) | yes | — |
verification_window_days | integer | yes | — |
warm_max_staleness_seconds | integer | yes | — |
warm_window_days | integer | yes | — |
Example response
{
"org_id": "org_0000000000000000",
"verification_window_days": 0,
"hot_window_days": 0,
"hot_max_staleness_seconds": 1,
"warm_window_days": 0,
"warm_max_staleness_seconds": 1,
"cold_max_staleness_seconds": 1,
"created_at": "2026-01-15T12:00:00.000Z",
"updated_at": "2026-01-15T12:00:00.000Z"
}Example request
curl -X GET https://api.codespar.dev/v1/orgs/{orgId}/audit/config \
-H "Authorization: Bearer $CODESPAR_API_KEY"PATCH /v1/orgs/{orgId}/audit/config
Update the chain verification windows and staleness budgets
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
orgId | string | yes | — |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
cold_max_staleness_seconds | number | no | — |
hot_max_staleness_seconds | number | no | — |
hot_window_days | number | no | — |
verification_window_days | number | no | — |
warm_max_staleness_seconds | number | no | — |
warm_window_days | number | no | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | object | The merged config broke an invariant. limit carries the ceiling on regulatory_minimum_violation, and the three merged window values on window_ordering_invalid. |
401 | object | No x-codespar-user header on a service credential. |
403 | object | The \{orgId\} is not the authenticated org, a project API key was used, or the named user is below admin. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
cold_max_staleness_seconds | integer | yes | — |
created_at | string (date-time) | yes | — |
hot_max_staleness_seconds | integer | yes | — |
hot_window_days | integer | yes | — |
initial_walk_completed_at | string,null (date-time) | yes | Null until the first forward walk has reached the chain tip. |
org_id | string | yes | — |
updated_at | string (date-time) | yes | — |
verification_window_days | integer | yes | — |
warm_max_staleness_seconds | integer | yes | — |
warm_window_days | integer | yes | — |
Example response
{
"org_id": "org_0000000000000000",
"verification_window_days": 0,
"hot_window_days": 0,
"hot_max_staleness_seconds": 1,
"warm_window_days": 0,
"warm_max_staleness_seconds": 1,
"cold_max_staleness_seconds": 1,
"created_at": "2026-01-15T12:00:00.000Z",
"updated_at": "2026-01-15T12:00:00.000Z"
}Example request
curl -X PATCH https://api.codespar.dev/v1/orgs/{orgId}/audit/config \
-H "Authorization: Bearer $CODESPAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"verification_window_days": 0,
"hot_window_days": 0,
"hot_max_staleness_seconds": 1,
"warm_window_days": 0,
"warm_max_staleness_seconds": 1,
"cold_max_staleness_seconds": 1
}'GET /v1/orgs/{orgId}/audit/health
How far the chain verifier got, and whether what it walked was linked
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
orgId | string | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
403 | object | The \{orgId\} in the path is not the authenticated org. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
actionable_status | "verifying" | "healthy" | "catching_up" | "link_unverifiable" | "degraded" | "broken" | yes | The field to alert on. link_unverifiable is not degraded: it means part of the chain was never verified either way, whereas degraded means tampering was detected. |
detail | string | yes | — |
incidents | object | yes | — |
initial_walk | object | yes | — |
last_checked_at | string (date-time) | yes | — |
last_sequence_number | integer | yes | — |
status | "healthy" | "degraded" | yes | — |
verification | object | yes | — |
Example response
{
"status": "healthy",
"last_sequence_number": 0,
"last_checked_at": "2026-01-15T12:00:00.000Z",
"detail": "string",
"actionable_status": "verifying",
"verification": {
"window_days": 0,
"watermark_sequence": 0,
"coverage_ratio": 0,
"hot_bucket_max_staleness_seconds": 1,
"chain_link_check": {
"unverifiable_segments": 0,
"oldest_unverifiable_segment": {
"from_sequence": 0,
"to_sequence": 0,
"reason": "sequence_gap",
"first_detected_at": "2026-01-15T12:00:00.000Z"
},
"writer_tip_link_unverifiable": true
}
},
"incidents": {
"open_count": 1,
"acknowledged_count_30d": 1,
"open_truncated": true,
"open": [
{
"id": "obj_0000000000000000",
"detected_at": "2026-01-15T12:00:00.000Z",
"detected_at_sequence": 0
}
]
},
"initial_walk": {
"in_progress": true,
"events_processed": 0
}
}Example request
curl -X GET https://api.codespar.dev/v1/orgs/{orgId}/audit/health \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/orgs/{orgId}/audit/incidents
List chain-integrity incidents
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
orgId | string | yes | — |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
status | string | no | Comma-separated, from open, acknowledged and all; all wins over anything sent with it. Default open. Unknown tokens are DROPPED rather than refused, and the request is only 400 invalid_status when nothing recognisable survives. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | No recognisable value survived the status filter. |
403 | object | The \{orgId\} in the path is not the authenticated org. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
incidents | array of object | yes | — |
Example response
{
"incidents": [
{
"id": "obj_0000000000000000",
"org_id": "org_0000000000000000",
"detected_at": "2026-01-15T12:00:00.000Z",
"detected_at_sequence": 0,
"status": "open",
"anpd_notification_status": "not_required",
"created_at": "2026-01-15T12:00:00.000Z"
}
]
}Example request
curl -X GET https://api.codespar.dev/v1/orgs/{orgId}/audit/incidents \
-H "Authorization: Bearer $CODESPAR_API_KEY"POST /v1/orgs/{orgId}/audit/incidents/{id}/acknowledge
Acknowledge a chain-integrity incident and write the acknowledgement into the chain
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | — |
orgId | string | yes | — |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
affected_from_sequence | number,null | no | Send with affected_to_sequence or with neither; one without the other is 400 paired_required. The route checks only that the value is a JSON number and that from is not greater than to. It does NOT check integrality, so this schema does not claim an integer the route would accept a fraction for; send whole numbers, because the column behind it is an integer. |
affected_to_sequence | number,null | no | Paired with affected_from_sequence; same rules. |
anpd_notification_status | "not_required" | "notified" | yes | Required and terminal. pending_assessment is refused with 400 pending_assessment_not_terminal: it is a console state and is never persisted. |
incident_reference | string,null | no | Optional. Control-stripped first; the 256 character ceiling is applied to the stripped value. Unlike resolution_summary this one is not trimmed and an empty string is accepted. |
personal_data_affected | boolean | yes | — |
resolution_summary | string | yes | Required, and whitespace alone does not satisfy it. The route strips C0 control characters and DEL, then refuses a value whose TRIMMED remainder is empty with 400 field_invalid / empty — so " " is rejected, not accepted. The 8000 character ceiling is then applied to the stripped value BEFORE trimming, so surrounding whitespace does count against the limit even though it cannot satisfy the emptiness check. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | object | A terminal ANPD status is required, or one field failed its check. field names it and reason is one of empty, too_long, invalid_type, invalid_enum, paired_required or range_inconsistent; limit is present only on too_long. resolution_summary reports empty both when it is missing or not a string and when it is present but blank after trimming. |
401 | object | No x-codespar-user header on a service credential. |
403 | object | A project API key cannot acknowledge, or the named user is below admin. |
404 | object | No such incident for this org. |
409 | object | Already acknowledged. The current row is attached, so a retry needs no second read. |
503 | object | The per-org chain lock was not available. Nothing was written; retry. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
chain_sequence_number | integer | yes | Sequence of the chain entry this acknowledgement appended. |
incident | object | yes | — |
Example response
{
"incident": {
"id": "obj_0000000000000000",
"org_id": "org_0000000000000000",
"detected_at": "2026-01-15T12:00:00.000Z",
"detected_at_sequence": 0,
"status": "open",
"anpd_notification_status": "not_required",
"created_at": "2026-01-15T12:00:00.000Z"
},
"chain_sequence_number": 0
}Example request
curl -X POST https://api.codespar.dev/v1/orgs/{orgId}/audit/incidents/{id}/acknowledge \
-H "Authorization: Bearer $CODESPAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"resolution_summary": "string",
"anpd_notification_status": "not_required",
"personal_data_affected": true
}'POST /v1/orgs/{orgId}/data-subjects/{userId}/anonymize
Erase a data subject's personal data across the audit chain (LGPD Art. 18)
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
orgId | string | yes | — |
userId | string | yes | 1 to 256 characters. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | \{userId\} was empty or over 256 characters. |
403 | object | The \{orgId\} in the path is not the authenticated org. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
deferred_entries | array of object | yes | — |
dsr_event_entry_hash | string | yes | — |
dsr_id | string | yes | The entry hash of the dsr_request chain event this call wrote. |
rows_anonymized_immediately | integer | yes | — |
rows_deferred | integer | yes | — |
Example response
{
"dsr_id": "dsr_0000000000000000",
"dsr_event_entry_hash": "string",
"rows_anonymized_immediately": 0,
"rows_deferred": 0,
"deferred_entries": [
{
"event_id": "event_0000000000000000",
"anonymize_after": "2026-01-15T12:00:00.000Z"
}
]
}Example request
curl -X POST https://api.codespar.dev/v1/orgs/{orgId}/data-subjects/{userId}/anonymize \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/orgs/{orgId}/mandates
List the org's mandates
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
orgId | string | yes | — |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
agent_id | string | no | — |
created_after | integer,null | no | — |
limit | integer | no | — |
status | "active" | "revoked" | "expired" | no | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | The query failed the schema; details.issues carries the Zod issues. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
count | integer | yes | Length of mandates, not a total. |
mandates | array of object | yes | — |
Example response
{
"mandates": [
{
"id": "obj_0000000000000000",
"org_id": "org_0000000000000000",
"agent_id": "agt_0000000000000000",
"type": "payment",
"status": "active",
"format_version": 0,
"secret_version": 0,
"amount": "1000",
"remaining_amount": "1000",
"currency": "BRL",
"purposes": [
"string"
],
"expires_at": "2026-01-15T12:00:00.000Z",
"signature": "string",
"authorized_by": "string",
"created_at": "2026-01-15T12:00:00.000Z"
}
],
"count": 1
}Example request
curl -X GET https://api.codespar.dev/v1/orgs/{orgId}/mandates \
-H "Authorization: Bearer $CODESPAR_API_KEY"POST /v1/orgs/{orgId}/mandates
Issue an org-side mandate (off by default, see the 501)
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
orgId | string | yes | — |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | yes | — |
amount | string | yes | — |
currency | string | yes | — |
denomination | string,null | no | — |
expires_at | integer | yes | — |
max_amount | string,null | no | — |
parent_id | string,null | no | — |
purposes | array of string | yes | — |
type | "payment" | "subscription" | "delegation" | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
201 | object | object | OK |
400 | object | The body failed the schema (details.issues carries the Zod issues), expires_at was not in the future, or a purpose was not printable ASCII. |
403 | object | A policy rule refused issuance. details carries reason, ruleType and ruleId, plus approval_id and expires_at when the rule opened an approval instead of denying outright. |
413 | object | The policy input was too large to evaluate. |
501 | object | Org-side issuance is disabled on this deployment. No mandate was created. |
503 | object | The policy engine could not evaluate the request. Nothing was evaluated and nothing was issued; retry. |
Example response
{
"mandate_id": "mandate_0000000000000000",
"signed_token": "string",
"format_version": 3,
"agent_did": "did:web:codespar.dev:org:agent",
"kid": "string",
"principal_kyc_verified": false,
"expires_at": "2026-01-15T12:00:00.000Z"
}Example request
curl -X POST https://api.codespar.dev/v1/orgs/{orgId}/mandates \
-H "Authorization: Bearer $CODESPAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "agt_0000000000000000",
"type": "payment",
"amount": "1000",
"currency": "BRL",
"purposes": [
"string"
],
"expires_at": 0
}'GET /v1/orgs/{orgId}/mandates/{id}
Read one mandate with its consumption history
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | — |
orgId | string | yes | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
404 | object | No such mandate for this org. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | yes | — |
amount | string | yes | Decimal string. |
authorized_by | string | yes | — |
consumptions | array of object | yes | — |
created_at | string (date-time) | yes | — |
currency | string | yes | — |
denomination | string,null | yes | — |
expired_at | string,null (date-time) | yes | — |
expires_at | string (date-time) | yes | — |
format_version | integer | yes | — |
id | string | yes | mnd_ prefixed. |
max_amount | string,null | yes | — |
org_id | string | yes | — |
parent_id | string,null | yes | — |
purposes | array of string | yes | — |
remaining_amount | string | yes | Decimal string, and it MOVES. This is the aggregate cap still available on the mandate: POST /v1/wallets/\{id\}/execute charges this mandate before the payment is attempted, decrementing this value and recording the consumption in one transaction. A spend that would take it below zero is refused with mandate_cap_exceeded rather than clamped, so this never goes negative. |
revocation_reason | string,null | yes | — |
revoked_at | string,null (date-time) | yes | — |
secret_version | integer | yes | — |
signature | string | yes | — |
status | "active" | "revoked" | "expired" | yes | Closed by the table's own CHECK constraint. |
type | "payment" | "subscription" | "delegation" | yes | — |
Example response
{
"id": "obj_0000000000000000",
"org_id": "org_0000000000000000",
"agent_id": "agt_0000000000000000",
"type": "payment",
"status": "active",
"format_version": 0,
"secret_version": 0,
"amount": "1000",
"remaining_amount": "1000",
"currency": "BRL",
"purposes": [
"string"
],
"expires_at": "2026-01-15T12:00:00.000Z",
"signature": "string",
"authorized_by": "string",
"created_at": "2026-01-15T12:00:00.000Z",
"consumptions": [
{
"id": "obj_0000000000000000",
"mandate_id": "mandate_0000000000000000",
"amount": "1000",
"call_purpose": "string",
"tool_call_id": "tc_0000000000000000",
"consumed_at": "2026-01-15T12:00:00.000Z"
}
]
}Example request
curl -X GET https://api.codespar.dev/v1/orgs/{orgId}/mandates/{id} \
-H "Authorization: Bearer $CODESPAR_API_KEY"POST /v1/orgs/{orgId}/mandates/{id}/revoke
Revoke a mandate
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | — |
orgId | string | yes | — |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | no | Free text, trimmed. An absent, non-string or blank value is recorded as revoked by operator. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
404 | object | No such mandate for this org. |
409 | object | The mandate was already revoked. |
410 | object | The mandate had already expired. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
prior_status | "active" | yes | — |
revoked_at | string (date-time) | yes | — |
Example response
{
"revoked_at": "2026-01-15T12:00:00.000Z",
"prior_status": "active"
}Example request
curl -X POST https://api.codespar.dev/v1/orgs/{orgId}/mandates/{id}/revoke \
-H "Authorization: Bearer $CODESPAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"reason": "string"
}'