Skip to content

List pending requests the caller is the one to decide

GET
/account/requests/incoming

The non-operator decision queue: pending requests this caller can act on without holding any capability, oldest first.

No capability is required and none would help — the gate is a join, not a check. This exists because /admin/requests is gated on requests.read / share.grant, capabilities an artist has no reason to hold, which left the people with the strongest claim to decide unable to reach the queue.

Two disjoint sets, joined on two different facts:

  • Access requests against assets the caller OWNS (#881), joined on assets.owner_user_ref. Live assets only — an owner has no decision to make about access to something they deleted.
  • Restoration appeals against items the caller DELETED (#931), joined on the target’s deleted_by_user_ref across all three soft-deletable kinds. Keyed to the deleter rather than the owner because the owner IS the requester here, and auth.CanRestoreDeleted gives the undo to whoever performed the delete.

They cannot overlap: the first requires a live asset, the second a soft-deleted target.

Decisions go to POST /admin/requests/{id}/decide, whose gate is the authority here — decidable_by_caller on each row is that same gate, computed rather than restated.

limit
integer
default: 50 >= 1 <= 200
offset
integer
0

Pending requests against the caller’s own assets.

object
items
required
Array<object>

A resource_request row. The state machine is pending → granted / denied (admin decision); granted → expired (CapabilitySweeper cascade). Terminal states admit no further transitions.

object
id
required
string format: uuid
requester_user_ref
required
integer format: int64
target_kind
required

Which table target_id refers to. Access requests (#881) are always asset; restoration appeals (#931) may name any of the three soft-deletable kinds.

string
Allowed values: asset post collection
target_id
required

The requested object, in the table named by target_kind. Called target_asset_id before #931, when the workflow could only ever name an asset.

string format: uuid
requested_capability
required

The capability code this request names. Two of them are inert markers that confer nothing and exist only to TYPE the row for its decide gate:

  • content.access.request — “may I see this asset” (#881). Decidable by the asset’s owner, share.grant, or system.admin.
  • content.restore.request — “please undo this delete” (#931). Decidable ONLY by whoever deleted the target, or by system.admin. share.grant does not qualify: authority over sharing is not authority over moderation. Granting one performs the restore; it writes no capability grant.
string
decidable_by_caller

True when THIS caller may decide THIS row right now, computed by the same gate the decide endpoint applies. Populated on the queue listings (/admin/requests, /account/requests/incoming) and absent elsewhere.

It exists because the two queues have different gates and the admin queue is readable by people who cannot act on every row it contains: share.grant sees restoration appeals but may not decide them. Rendering a decide control from row presence alone would offer a button that 403s.

boolean
reason
string
state
required
string
Allowed values: pending granted denied expired
decided_at
string format: date-time
nullable
decided_by_user_ref
integer format: int64
nullable
decision_reason
string
expires_at

On granted requests, the linked grant’s auto-expiry. Null means permanent.

string format: date-time
nullable
requested_at
required
string format: date-time
total
required

Total pending count against the caller’s assets.

integer format: int64

Authentication required, missing, or invalid

object
error
required

Human-readable error summary

string
Example
the request could not be completed
Example
{
"error": "authentication required: sign in and retry with a valid session or API token"
}