# Withdraw an app's listing application

> The apps.listing.withdraw operation: POST /api/v1/apps/{id}/listing/withdraw in the REST API and the apps_listing_withdraw tool in the MCP server.

Withdraws an application that waits for review (`pending`) or for your changes (`changes_requested`). The
application stays saved for a later `apps.listing.submit`. A first application goes back to `not_submitted`; a
re-review of an approved app goes back to `approved`, still listed for its approved scopes only.

## At a glance

- **REST:** `POST /api/v1/apps/{id}/listing/withdraw`
- **MCP tool:** `apps_listing_withdraw`
- **Operation ID:** `apps.listing.withdraw`
- **Scope:** Organization
- **Permission:** `agents:admin`
- **Risk tier:** `write`
- **Dry run:** Supported (send `Ownrecord-Dry-Run: true`)
- **Idempotency:** `Idempotency-Key` required
- **Modes:** Test and live
- **Authentication:** API key with the `agents:admin` scope
- **Since:** M13

## Request

### Path parameters

| Field | Type       | Description |
| ----- | ---------- | ----------- |
| `id`  | `ocl_…` ID |             |

### Body

This operation takes no body.

## Response

`200 OK` with a JSON object:

| Field              | Type                                                                                                                         | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- | ----------- |
| `id`               | `ocl_…` ID                                                                                                                   |             |
| `object`           | `"app_listing"`                                                                                                              |             |
| `ownerOrgId`       | `org_…` ID                                                                                                                   |             |
| `name`             | string                                                                                                                       |             |
| `publisher`        | string                                                                                                                       |             |
| `visibility`       | one of `private`, `listed`                                                                                                   |             |
| `appStatus`        | one of `active`, `disabled`                                                                                                  |             |
| `status`           | one of `not_submitted`, `pending`, `changes_requested`, `approved`, `rejected`                                               |             |
| `listed`           | boolean                                                                                                                      |             |
| `scopes`           | array of one of 84 values, e.g. `org:read`, `org:write`, `org:admin` (all in the OpenAPI document)                           |             |
| `approvedScopes`   | array of one of 84 values, e.g. `org:read`, `org:write`, `org:admin` (all in the OpenAPI document) or null                   |             |
| `pendingScopes`    | array of one of 84 values, e.g. `org:read`, `org:write`, `org:admin` (all in the OpenAPI document)                           |             |
| `submittedAt`      | date-time or null                                                                                                            |             |
| `decidedAt`        | date-time or null                                                                                                            |             |
| `reason`           | string or null                                                                                                               |             |
| `application`      | object or null                                                                                                               |             |
| `history`          | array of object                                                                                                              |             |
| `history[].action` | one of `submitted`, `withdrawn`, `approved`, `rejected`, `changes_requested`, `scopes_added`, `identity_changed`, `unlisted` |             |
| `history[].at`     | date-time                                                                                                                    |             |
| `history[].by`     | string or null                                                                                                               |             |
| `history[].reason` | string or null                                                                                                               |             |
| `history[].scopes` | array of one of 84 values, e.g. `org:read`, `org:write`, `org:admin` (all in the OpenAPI document)                           |             |
| `version`          | integer                                                                                                                      |             |

## Examples

### Withdraw a first application

```http
POST /api/v1/apps/ocl_01m4ttwd3veh9apbewxheq5xha/listing/withdraw
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
```

Response (`200`):

```json
{
  "id": "ocl_01m4ttwd3veh9apbewxheq5xha",
  "object": "app_listing",
  "ownerOrgId": "org_01m4ttwd3veh9apbewxheq5xhb",
  "name": "Ledgerly AI",
  "publisher": "Ledgerly AI B.V.",
  "visibility": "listed",
  "appStatus": "active",
  "status": "not_submitted",
  "listed": false,
  "scopes": ["filings:read", "filings:write", "tasks:read", "tasks:write", "ledger:read"],
  "approvedScopes": null,
  "pendingScopes": ["filings:read", "filings:write", "tasks:read", "tasks:write", "ledger:read"],
  "submittedAt": "2026-10-30T09:00:00.000Z",
  "decidedAt": null,
  "reason": null,
  "application": {
    "publisher": {
      "legalName": "Ledgerly AI B.V.",
      "country": "NL",
      "websiteUrl": "https://ledgerly.example",
      "contact": {
        "name": "Mira de Vries",
        "email": "partners@ledgerly.example"
      }
    },
    "privacyPolicyUrl": "https://ledgerly.example/privacy",
    "questionnaire": {
      "version": 1,
      "answers": [
        {
          "questionId": "data_location",
          "answer": null,
          "details": "AWS eu-central-1 (Frankfurt), Germany"
        },
        {
          "questionId": "encryption_in_transit",
          "answer": "yes",
          "details": null
        },
        {
          "questionId": "encryption_at_rest",
          "answer": "yes",
          "details": null
        },
        {
          "questionId": "credential_storage",
          "answer": "yes",
          "details": null
        },
        {
          "questionId": "staff_access",
          "answer": "yes",
          "details": null
        },
        {
          "questionId": "incident_response",
          "answer": "yes",
          "details": null
        },
        {
          "questionId": "subprocessors",
          "answer": "yes",
          "details": "AWS (hosting), Postmark (email)"
        },
        {
          "questionId": "model_training",
          "answer": "no",
          "details": null
        },
        {
          "questionId": "data_deletion",
          "answer": "yes",
          "details": "Within 30 days of uninstalling"
        },
        {
          "questionId": "vulnerability_management",
          "answer": "yes",
          "details": null
        }
      ]
    },
    "scopeJustifications": [
      {
        "scope": "filings:read",
        "justification": "Reads filing periods to prepare each return."
      },
      {
        "scope": "filings:write",
        "justification": "Records the prepared return and its submission."
      },
      {
        "scope": "tasks:read",
        "justification": "Finds the filing tasks assigned to the app."
      },
      {
        "scope": "tasks:write",
        "justification": "Claims and completes filing tasks."
      },
      {
        "scope": "ledger:read",
        "justification": "Reconciles the return with the tax payable accounts."
      }
    ],
    "partnerTermsVersion": "1.0",
    "submittedBy": "usr_01m4ttwd3veh9apbewxheq5xhf"
  },
  "history": [
    {
      "action": "submitted",
      "at": "2026-10-30T09:00:00.000Z",
      "by": "usr_01m4ttwd3veh9apbewxheq5xhf",
      "reason": null,
      "scopes": []
    },
    {
      "action": "withdrawn",
      "at": "2026-10-30T11:00:00.000Z",
      "by": "usr_01m4ttwd3veh9apbewxheq5xhf",
      "reason": null,
      "scopes": []
    }
  ],
  "version": 4
}
```

## Errors

| Code                                                                                                         | HTTP status | When                                                          | What to do                                                                                                               |
| ------------------------------------------------------------------------------------------------------------ | ----------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [`app_listing_not_withdrawable`](https://ownrecord.io/docs/reference/errors.md#app_listing_not_withdrawable) | 409         | The app has no application waiting for review or for changes. | Only an application that is `pending` or `changes_requested` can be withdrawn. Read the listing with `apps.listing.get`. |
| [`resource_not_found`](https://ownrecord.io/docs/reference/errors.md#resource_not_found)                     | 404         | Your organization registered no app with this ID.             | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.                     |
| [`version_conflict`](https://ownrecord.io/docs/reference/errors.md#version_conflict)                         | 409         | The app changed at the same moment; retry.                    | Fetch the object again and retry the change.                                                                             |
| [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#permission_denied)                       | 403         | You can't manage the organization's apps.                     | Ask an organization owner or admin for a role or scope that allows this action.                                          |

It can also return these [common errors](https://ownrecord.io/docs/reference.md#common-errors): [`validation_failed`](https://ownrecord.io/docs/reference/errors.md#validation_failed), [`api_version_unsupported`](https://ownrecord.io/docs/reference/errors.md#api_version_unsupported), [`invalid_json`](https://ownrecord.io/docs/reference/errors.md#invalid_json), [`unsupported_media_type`](https://ownrecord.io/docs/reference/errors.md#unsupported_media_type), [`authentication_required`](https://ownrecord.io/docs/reference/errors.md#authentication_required), [`api_key_invalid`](https://ownrecord.io/docs/reference/errors.md#api_key_invalid), [`idempotency_key_required`](https://ownrecord.io/docs/reference/errors.md#idempotency_key_required), [`idempotency_key_reused`](https://ownrecord.io/docs/reference/errors.md#idempotency_key_reused), [`idempotency_in_progress`](https://ownrecord.io/docs/reference/errors.md#idempotency_in_progress), [`approval_required`](https://ownrecord.io/docs/reference/errors.md#approval_required), [`approval_rejected`](https://ownrecord.io/docs/reference/errors.md#approval_rejected), [`approval_expired`](https://ownrecord.io/docs/reference/errors.md#approval_expired), [`stale_approval`](https://ownrecord.io/docs/reference/errors.md#stale_approval), [`approval_policy_denied`](https://ownrecord.io/docs/reference/errors.md#approval_policy_denied), [`rate_limited`](https://ownrecord.io/docs/reference/errors.md#rate_limited), [`internal_error`](https://ownrecord.io/docs/reference/errors.md#internal_error).
