mobieusKnow mobieusCore API — Marketplace, files, and moderation

mobieusCore API — Marketplace, files, and moderation

3 min read · 486 words · 2 revisions · Updated Jun 14, 2026

Marketplace, files, and moderation endpoints

The 2026-05-29 expansion added programmatic access to the marketplace listings, file uploads, and the moderation queue. Every endpoint here is scoped, paginated, and tenant-isolated like the rest of the v1 surface.

Marketplace listings

GET /api/v1/listings

Lists every listing on the tenant, newest first.

Query parameters:

Param Type Example
status string active, pending, sold, withdrawn, expired
seller_id integer 312
category_id integer 7
cursor string opaque
limit integer 25 (max 100)

Response shape:

{
  "data": [
    {
      "id": 42, "slug": "atari-2600-light-sixer",
      "title": "Atari 2600 Light Sixer",
      "description": "Working, original box…",
      "price_cents": 12500,
      "quantity": 1, "quantity_remaining": 1,
      "condition_rating": "good",
      "location": { "country": "US", "region": "NY", "city": "Brooklyn" },
      "status": "active",
      "category": { "id": 7, "name": "Atari 2600" },
      "seller":   { "id": 312, "username": "retroseller" },
      "created_at": "2026-05-29T13:00:00Z",
      "expires_at": "2026-06-28T13:00:00Z"
    }
  ],
  "next_cursor": "NDI=",
  "request_id": "req_…"
}

GET /api/v1/listings/{id}

Returns one listing by id with the same shape.

Scope required: listings:read.

File uploads

GET /api/v1/files

Lists every approved file on the tenant. Files still in quarantine are not exposed.

Query parameters:

Param Type Example
area_slug string atari-2600-disks
uploader_id integer 312
cursor string opaque
limit integer 25 (max 100)

Response shape:

{ "data": [{
    "id": 18, "title": "Centipede (1981)",
    "description": "Atari Centipede dump.",
    "original_name": "centipede.bin",
    "mime_type": "application/octet-stream",
    "size_bytes": 16384,
    "download_count": 4,
    "area":     { "slug": "atari-2600-disks", "name": "Atari 2600 disks" },
    "uploader": { "id": 312, "username": "retroseller" },
    "created_at": "2026-05-29T13:05:00Z"
  }], "next_cursor": null, "request_id": "req_…" }

GET /api/v1/files/{id}

Returns one approved file by id.

Scope required: files:read.

Moderation

GET /api/v1/reports

Lists moderation reports. Filter by status or reported_user_id.

Description is omitted from the list response for size; fetch a single report to get the full body.

GET /api/v1/reports/{id}

Returns a single report including the full description field.

POST /api/v1/reports/{id}/dismiss

Marks the report status='resolved' with resolution_notes prefixed Dismissed via API:. Body:

{ "reason": "No violation found." }

Returns 400 already_resolved if the report is already resolved.

POST /api/v1/reports/{id}/resolve

Same shape as dismiss but the resolution notes are prefixed Resolved via API:. Use this when the report is valid and you took some action externally that you want recorded.

GET /api/v1/moderation/actions

Returns every moderator action recorded on the tenant. Filter by action (e.g. forum.ban, moderation.warn), actor_id, or affected_user_id.

Scopes:

  • reports:readGET endpoints + the moderation-actions log
  • reports:manage — the two POST endpoints (dismiss, resolve)

Best practices

  • Page in batches: cursor pagination is forward-only; persist the last next_cursor you saw so you can resume without re-walking.
  • Read with the smallest scope: a key with only reports:read cannot accidentally close a report.
  • Subscribe to webhooks for listing.*, file.uploaded, report.created, and moderation.action_taken rather than polling — webhooks are delivered within ~60 seconds of the underlying write.
Contributors:
S
Last edited by system · KB drift-audit reconciliation 2026-06-14: corrected to match dev (report deliverables).
Created May 29, 2026
Was this article helpful?

Discussion

Sign in to start the discussion.