get-approval
Read one approval in this project: its status, who decided it, the reason and the choice they gave. Needs no grant. It returns the same shape as GET /v1/approvals/{id}.
curl -sS -X POST https://fabric.wexa.ai/mcp/$FABRIC_PROJECT_ID \
-H "authorization: Bearer $FABRIC_API_KEY" \
-H "Mcp-Session-Id: $MCP_SESSION_ID" \
-H "content-type: application/json" -H "accept: application/json" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get-approval","arguments":{"approval_id":"ar_6abbab02fb130d22ba652a81"}}}'{
"content": [
{
"type": "text",
"text": "{\"lifecycle_id\":\"qlc_000240\",\"result\":{\"id\":\"ar_6abbab02fb130d22ba652a81\",\"status\":\"approved\",\"what\":\"Pay supplier (Python wait)\",\"risk\":\"medium\",\"reference\":\"inbox-py-approve\",\"decided_by\":\"6abbaa9b4a684dc3e5a7bda0\",\"decision_reason\":\"Supplier verified in the console\"}}"
}
],
"isError": false
}Parameters
| Parameter | Type | Required | Notes |
|---|---|---|---|
approval_id | string | Required | Approval id, as returned by request-approval (ar_...). An approval in another project answers not found, the same as an id that does not exist. |
Show full response
A real response, captured from a live call to get-approval:
{
"content": [
{
"type": "text",
"text": "{\"lifecycle_id\":\"qlc_000241\",\"result\":{\"args\":null,\"created_at\":\"2026-09-29T12:11:46.83Z\",\"decided_at\":\"2026-09-29T12:14:38.712Z\",\"decided_by\":\"6abbaa9b4a684dc3e5a7bda0\",\"decision_reason\":\"Supplier verified in the console\",\"expires_at\":\"2026-10-01T12:11:46.83Z\",\"hard_expires_at\":\"2026-10-03T12:11:46.83Z\",\"id\":\"ar_6abbab02fb130d22ba652a81\",\"lifecycle_id\":\"\",\"reference\":\"inbox-py-approve\",\"requested_by\":\"6abbaa9b4a684dc3e5a7bda0\",\"risk\":\"medium\",\"scope\":{\"auth_kind\":\"\",\"grants\":null,\"org_id\":\"6abbaa9b4a684dc3e5a7bda1\",\"project_id\":\"6abbaa9b4a684dc3e5a7bdb1\",\"role\":\"\",\"user_id\":\"6abbaa9b4a684dc3e5a7bda0\"},\"status\":\"approved\",\"tool\":\"\",\"type\":\"app_request\",\"what\":\"Pay supplier (Python wait)\",\"why\":\"Decided in the Fabric console Inbox\"}}"
}
],
"isError": false
}More details
For an approval opened with request-approval, reference is the reference you passed. For how approvals are decided and resumed, see policy and approvals.
pending: Waiting for a decision. Final: no.overdue: Past its deadline (expires_at) and still waiting. It can still be decided. Final for an SDK wait.approved: A person approved it.decided_by,decided_at, andchoicewhen one was picked. Final.rejected: A person rejected it.decision_reasonsays why. Final.expired: Pasthard_expires_atwith no decision. It can no longer be decided. Final.
An SDK that waits for a decision stops at overdue, the same as the wait on a held tool call. To keep waiting for an overdue approval, call get-approval again later.
id(string): The approval id.type(string):app_requestfor an approval opened withrequest-approval.status(string): One of the statuses above.what,why(string): The title and reason the request was opened with.risk(string):low,mediumorhigh.payload(object): The details sent with the request, when there were any.choices,choice(array, string): The options offered, and the one the approver picked.requested_by(string): The user the request was made as.decided_by,decided_at(string): Who decided it, and when.decision_reason(string): The reason the approver gave. Always present on a rejection.consumed(boolean): Present andtrueonce a held tool call has used its approval.created_at,expires_at,hard_expires_at(string): When it was opened, its deadline, and when it expires.reference(string): The reference passed torequest-approval.
Not marked consequential: it only reads, is audited lightly and is never held for approval.
Every tool call works the same way: How every tool call works.