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.
/api/v1/apps/{id}/listing/withdrawWithdraws 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-Keyrequired - Modes: Test and live
- Authentication: API key with the
agents:adminscope - 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
POST /api/v1/apps/ocl_01m4ttwd3veh9apbewxheq5xha/listing/withdraw
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
Response (200):
{
"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 | 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 | 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 | 409 | The app changed at the same moment; retry. | Fetch the object again and retry the change. |
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: validation_failed, api_version_unsupported, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, idempotency_key_required, idempotency_key_reused, idempotency_in_progress, approval_required, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.