Dish Directory Admin API

The Admin API from Dish Directory — 138 operation(s) for admin.

Operations 207

GET /admin/backlinks/export Export directory submissions as CSV. Session admin only. #
POST /admin/test-sends Send one confirmed test call, text or postcard. #
POST /admin/voice/preview Preview a fixed spoken line with the selected voice. Session admin only. #
GET /admin/agent-runs The agent runs, newest first, filtered by status and agent. #
POST /admin/agent-runs Record one agent run: agent, command, input, status, output link, error and… #
PATCH /admin/agent-runs/{id} Finish a running agent run with its outcome: succeeded, failed or cancelled… #
PUT /admin/apps/{slug} Create or replace one app. Needs the apps:write scope or an admin session #
DELETE /admin/apps/{slug} Delete one app. Needs the apps:write scope or an admin session #
GET /admin/audit-log The audit log, newest first #
POST /admin/backup/export Snapshot the site database into private storage and record the run. #
GET /admin/backup/status The backup ledger and the last export #
PUT /admin/categories/{slug} Create or replace one category. #
DELETE /admin/categories/{slug} Delete one category that has no children and no listings. #
GET /admin/billing/subscriptions The subscriptions of this site, newest first, with the failed-payment state… #
PATCH /admin/billing/subscriptions/{id} Cancel one subscription of this site at Stripe, now or at the end of the paid… #
GET /admin/billing/invoices The Stripe invoices of one subscription of this site, newest first. #
POST /admin/billing/invoices/{id}/refund Refund the payment of one subscription invoice of this site, in part or in full. #
POST /admin/billing/retry Retry the failed renewal of a past_due subscription: pay its newest open… #
POST /admin/claims/{id} Approve or reject a manual claim #
DELETE /admin/claims/{id} Preview deletion by default. #
POST /admin/listings/{id}/owner Assign the owner of a listing by admin fiat: a verified manual claim, no email… #
DELETE /admin/listings/{id}/owner Revoke the owner of a listing: its verified claim expires and claimed_by clears. #
GET /admin/claims Claims, newest first. Filter by listing (id or slug) and status. #
GET /admin/guides List every guide of this site, drafts included. #
POST /admin/guides Create or replace one guide from a Markdown file. #
GET /admin/guides/{slug} Read one guide. Needs the content:read scope or an admin session #
PUT /admin/guides/{slug} Replace one guide from a Markdown file. #
PATCH /admin/guides/{slug} Publish or unpublish one guide. #
DELETE /admin/guides/{slug} Delete one guide. Needs the content:write scope or an admin session #
GET /admin/crm/export The filtered contacts as CSV #
PATCH /admin/crm/{id} Edit a contact's fields #
POST /admin/crm/{id} Add a note to a contact #
DELETE /admin/crm/{id} Remove a contact #
POST /admin/edits/{id} Accept, reject or spam a suggestion #
GET /admin/enrichment/requests The enrichment requests of the site, newest first, filtered by status. #
PATCH /admin/enrichment/requests/{id} Move one enrichment request on: open to running, then running to done (with… #
POST /admin/ads/campaigns Create one ad campaign through the ads relay. #
POST /admin/ads/campaigns/{id}/status Pause or resume one campaign through the ads relay. Audited. #
POST /admin/enrichment/run Ask for one enrichment run of this site. #
GET /admin/enrichment/runs The enrichment import log of the site, newest first. #
GET /admin/forms/export.csv The forms inbox as CSV #
POST /admin/mail Mark a message (read, spam, not-spam, archive) or send a mail. #
GET /admin/mail/recent The latest received mail, newest first, with the verification links and codes… #
GET /admin/support/tickets Support tickets, oldest first. One ticket per inbound mail thread. #
GET /admin/support/canned The canned support replies, finished: each text is ready to send. #
POST /admin/support/refund Refund the payment of one subscription invoice of this site for a support… #
POST /admin/support/takedown Record a takedown request and hand it to a human: the named ticket is escalated… #
POST /admin/support/legal Record a legal request and hand it to a human: the named ticket is escalated… #
GET /admin/support/requests Takedown and legal requests, oldest first. #
PATCH /admin/support/tickets/{id} Change one support ticket status (open, pending, resolved). Audited. #
POST /admin/support/tickets/{id}/escalate Hand one support ticket to a human, once. #
POST /admin/support/tickets/{id}/reply Answer the sender of one support ticket by mail, on the ticket thread, with… #
GET /admin/mail/{messageId}/attachments/{attachmentId} Download one attachment of a stored message #
GET /admin/monitoring/alerts The open alerts in the monitoring feed, newest first. #
GET /admin/monitoring/sites The site rollup: identity, the newest event of each kind and the open-alert… #
GET /admin/domains/{domain}/status The domain, DNS, routing and mailbox state. #
POST /admin/domains/{domain}/verify Re-read the Cloudflare state and cross-check it against a public resolver, one… #
POST /admin/leads/dispatch Start one parallel call run. Needs the leads:write scope or an admin session #
POST /admin/leads/drips Create, update or delete a drip sequence: a name plus ordered steps (template… #
POST /admin/leads/{id} Set lead status, request a call, set the script, send a text or a postcard… #
POST /admin/leads/kb Create or delete a knowledge-base document. #
GET /admin/leads/reconcile Billed lead charges plus call spend, per listing #
POST /admin/leads/scripts Create, update or delete a call script. #
POST /admin/leads/templates Create, update or delete a message template (text, call or postcard body with… #
GET /admin/link-exchanges The link exchanges, newest first: the site, the contact, the placement, the… #
GET /admin/link-exchanges/{id} Read one link exchange whole: the site, the contact, the last live-link check… #
POST /admin/link-exchanges/{id} Approve, reject, spam or recheck a link exchange #
GET /admin/listings List listings of every status (draft, pending, published, archived), ordered by… #
GET /admin/listings/{slug} Read one listing of any status by id or slug: every field, attributes… #
DELETE /admin/listings/{slug} Preview deletion by default, with per-table row counts in the plan. #
PATCH /admin/listings/{slug} Change some fields of one listing, by id or slug: editable import fields… #
PUT /admin/listings/{slug} Create or replace one listing at its slug. #
POST /admin/listings/{slug} Feature, unfeature or mark a listing real #
POST /admin/listings/bulk Validate up to 100 listing rows and return the plan with field diffs (dryRun… #
GET /admin/listings/{slug}/photos Uploaded photos of a listing, in display order. #
POST /admin/listings/{slug}/photos Add an upload to a listing: a multipart body with a file field (and alt), or… #
PATCH /admin/listings/{slug}/photos Put the photos in a new order in one call. #
PATCH /admin/listings/{slug}/photos/{photoId} Change the alt text or the sort order of one photo. #
DELETE /admin/listings/{slug}/photos/{photoId} Delete one uploaded photo and its R2 object. #
GET /admin/listings/{slug}/reviews The on-site reviews of one listing, newest first, every status, with the… #
POST /admin/listings/{slug}/reviews Add one on-site review to a listing. #
GET /admin/listings/{slug}/reviews/{rowId} Read one on-site review of a listing, with the listing's rating aggregate. #
PATCH /admin/listings/{slug}/reviews/{rowId} Edit the author name, rating or body of one on-site review. #
DELETE /admin/listings/{slug}/reviews/{rowId} Delete one on-site review. #
POST /admin/listings/{slug}/reviews/{rowId}/publish Publish one on-site review: it counts in the listing's rating aggregate at once. #
POST /admin/listings/{slug}/reviews/{rowId}/reject Reject one on-site review: it leaves the listing's rating aggregate at once. #
GET /admin/listings/{slug}/source-photos List source photos in display order, including hidden rows. #
PATCH /admin/listings/{slug}/source-photos Reorder all source photos, including hidden rows. Name every id exactly once. #
GET /admin/listings/{slug}/source-photos/{rowId} Read one source photo on this listing. Needs content:read or an admin session #
PATCH /admin/listings/{slug}/source-photos/{rowId} Edit source photo alt text. Dry run by default; set dryRun false to apply. #
DELETE /admin/listings/{slug}/source-photos/{rowId} Suppress a source photo and retain its identity. Dry run by default. #
GET /admin/listings/{slug}/source-reviews All copied platform reviews of one listing, hidden ones too. #
POST /admin/listings/{slug}/source-reviews Add one platform review to a listing. Dry run unless confirm=true. #
PATCH /admin/listings/{slug}/source-reviews/{rowId} Edit or hide one review. Dry run unless confirm=true. #
DELETE /admin/listings/{slug}/source-reviews/{rowId} Remove one review from public pages. Dry run unless confirm=true. #
GET /admin/listings/{slug}/source-ratings All copied platform ratings of one listing, hidden ones too. #
POST /admin/listings/{slug}/source-ratings Add one platform rating to a listing. Dry run unless confirm=true. #
PATCH /admin/listings/{slug}/source-ratings/{rowId} Edit or hide one rating. Dry run unless confirm=true. #
DELETE /admin/listings/{slug}/source-ratings/{rowId} Remove one rating from public pages. Dry run unless confirm=true. #
GET /admin/redirects The retired listing slugs (listing_redirects), newest first, with the listing… #
POST /admin/redirects Reserve one retired slug for a listing: the old permalink, the old listing URL… #
DELETE /admin/redirects/{id} Remove one redirect by its retired slug. #
GET /admin/moderation/queue Every pending submission, edit suggestion, manual claim, open report and… #
PATCH /admin/moderation/{id} Decide one queue item. #
GET /admin/moderation/ban The bans, newest first. An IP ban shows the hash. #
POST /admin/moderation/ban Ban an email address, an IP or the sender of a queue item. #
DELETE /admin/moderation/ban Lift one ban by its id. Needs the submissions:review scope or an admin session #
GET /admin/newsletter/api-keys The newsletter API keys. Needs the newsletter:write scope or an admin session #
POST /admin/newsletter/api-keys Create or revoke a newsletter API key. Audited. #
GET /admin/newsletter/contacts A page of subscribers, or the filtered CSV export with format=csv #
POST /admin/newsletter/contacts Add, change or remove one subscriber, mail the confirmation to selected pending… #
GET /admin/newsletter/campaigns The campaigns, newest first, without bodies. #
POST /admin/newsletter/campaigns Create a campaign draft. Needs the newsletter:write scope or an admin session #
GET /admin/newsletter/campaigns/{id} One campaign with its body. Needs the newsletter:write scope or an admin session #
PATCH /admin/newsletter/campaigns/{id} Save a draft or scheduled campaign body. #
DELETE /admin/newsletter/campaigns/{id} Delete a campaign. Needs the newsletter:write scope or an admin session #
POST /admin/newsletter/campaigns/{id} Schedule, cancel, queue, duplicate or test-send a campaign. #
GET /admin/reports/leads Lead counts by status and cost per lead by channel (call, text, postcard) and… #
GET /admin/reports/revenue Gross, refunded and net revenue per currency for a period, from Stripe events… #
GET /admin/reports/traffic Search Console clicks, impressions, CTR and position for a period, with the top… #
GET /admin/seo/audit The index audit of the site (robots, sitemap, sample pages) plus the sitemap… #
POST /admin/seo/indexnow Push the listings and guides that changed to IndexNow now. Audited. #
POST /admin/seo/resubmit-sitemap Submit the sitemap to IndexNow and add it to Search Console. Audited. #
GET /admin/settings The site settings #
PUT /admin/settings Create or update one setting #
DELETE /admin/settings Remove one setting #
POST /admin/revalidate Expire the cached public reads (listings, sources) so the next read sees a… #
PUT /admin/sources/{key} Create or replace one import source. #
DELETE /admin/sources/{key} Delete one source that has no listings and no import runs. #
GET /admin/submissions The submission queue, newest first #
POST /admin/submissions/{id} Approve, reject, spam or merge a submission #
GET /admin/tokens The service tokens, with hints and metadata only #
POST /admin/tokens Issue a service token. The secret comes back in this response only #
DELETE /admin/tokens/{id} Revoke a service token #
POST /admin/outreach/messages/{id} Edit, approve, cancel or send one outreach email message. #
POST /admin/outreach/reconcile Read the mail inbox for replies and bounces that name a sent outreach message. #
PUT /admin/outreach/sender Set the outreach sender: name, mailbox, postal address, DKIM selector, warm-up… #
POST /admin/outreach/suppressions Add or lift one outreach suppression. An add closes the targets it covers. #
GET /admin/outreach/campaigns Outreach campaigns over the CRM, newest first, 50 a page (limit up to 100). #
POST /admin/outreach/campaigns Create one draft outreach campaign: a name, a channel (call, email, text or… #
GET /admin/outreach/contacts The CRM contacts a campaign could reach on one channel, 50 a page, oldest first… #
POST /admin/outreach/targets/{id} Pause, resume, mark replied or complained, draft the one follow-up, or set the… #
GET /admin/products Every product, hidden ones too, by category, featured, rank. #
POST /admin/products Create or replace one product by slug: an idempotent upsert that also restores… #
POST /admin/products/bulk Upsert up to 200 products by slug from a JSON array, { rows }, or a text/csv… #
GET /admin/products/{slug} One product, deleted or not. #
PATCH /admin/products/{slug} Change some fields of one product. The result must pass the full product checks. #
DELETE /admin/products/{slug} Soft-delete one product: it leaves the site and keeps its row. #
GET /admin/product-categories Every product category, hidden ones too. #
POST /admin/product-categories Create or replace one product category by slug: an idempotent upsert that also… #
POST /admin/product-categories/bulk Upsert up to 200 product categories by slug from a JSON array, { rows }, or a… #
GET /admin/product-categories/{slug} One product category, deleted or not. #
PATCH /admin/product-categories/{slug} Change some fields of one product category. #
DELETE /admin/product-categories/{slug} Soft-delete one product category. #
GET /admin/academy/templates Every certificate template, the default first. #
GET /admin/academy/templates/{slug} One certificate template. Needs the academy:read scope or an admin session #
PUT /admin/academy/templates/{slug} Create or replace one certificate template by slug: an idempotent upsert that… #
DELETE /admin/academy/templates/{slug} Delete one certificate template. #
POST /admin/academy/templates/{slug}/default Make one certificate template the default. #
GET /admin/academy/courses/{slug}/lessons The lessons of a course by position, then slug. #
GET /admin/academy/courses/{slug}/lessons/{lesson} One lesson of a course. Needs the academy:read scope or an admin session #
PUT /admin/academy/courses/{slug}/lessons/{lesson} Create or replace one lesson by slug: an idempotent upsert. #
DELETE /admin/academy/courses/{slug}/lessons/{lesson} Hard-delete one lesson. Its questions stay and lose their lesson. #
GET /admin/academy/courses/{slug}/images The images of a course, oldest first, with the site path of each. #
POST /admin/academy/courses/{slug}/images Add one image to a course. #
DELETE /admin/academy/courses/{slug}/images/{id} Hard-delete one image and its stored file. #
GET /admin/academy/courses/{slug}/questions The questions of a course, oldest first, with the correct flag of each option. #
POST /admin/academy/courses/{slug}/questions Create one exam question; the answer carries its qst_ id. #
GET /admin/academy/courses/{slug}/questions/{id} One question by qst_ id, with the correct flag of each option. #
PUT /admin/academy/courses/{slug}/questions/{id} Replace one question by qst_ id; the same checks as create. #
DELETE /admin/academy/courses/{slug}/questions/{id} Hard-delete one question by qst_ id. #
GET /admin/academy/courses Courses by sort order, with lesson and question counts, all and published. #
GET /admin/academy/courses/{slug} One live course with its lesson and question counts. #
PUT /admin/academy/courses/{slug} Create or replace one course by slug: an idempotent upsert. #
DELETE /admin/academy/courses/{slug} Soft-delete one course: the row and its certificates stay. #
POST /admin/academy/courses/{slug}/publish Publish one course. Repeating it changes nothing. #
POST /admin/academy/courses/{slug}/unpublish Unpublish one course. Repeating it changes nothing. #
GET /admin/academy/students Users with an enrollment, a certificate or a membership, the most recently… #
GET /admin/academy/students/{userId} One student with enrollments, attempt scores and pass flags (never answers)… #
GET /admin/academy/memberships Membership rows, newest first, with the owner's email. #
POST /admin/academy/memberships Grant a comp membership to a user. #
DELETE /admin/academy/memberships/{id} Revoke a comp membership: the row stays as history and access ends now. #
GET /admin/academy/certificates Certificates, newest first, with the revoke reason. #
POST /admin/academy/certificates Issue one certificate by hand, with no exam attempt. #
GET /admin/academy/certificates/{code} One certificate by code, in any spelling: upper or lower case, with or without… #
POST /admin/academy/certificates/{code}/revoke Revoke one certificate with a reason of 3 to 300 characters. #
POST /admin/academy/certificates/{code}/reinstate Clear the revoke of one certificate; it reads valid or expired again by its… #
POST /admin/academy/certificates/{code}/extend Set a later expiry (an ISO date in the future, after the current one) or… #
PUT /admin/places Create or replace one place by its path. #
DELETE /admin/places Delete one place that has no child places and no listings. #
GET /admin/users The accounts, newest first, with role, admin flag, live session count and owned… #
POST /admin/users Create one account without sending mail. The role defaults to member. #
POST /admin/users/invite Invite an address: create the account with the role, or reactivate a… #
GET /admin/users/{id}/sessions The live sessions of one account, newest first: id, dates, address and user… #
DELETE /admin/users/{id}/sessions Revoke one session of the account (sessionId) or all of them. #
DELETE /admin/users/{id} Offboard one account. #
PATCH /admin/users/{id} Set one account's role. #
GET /admin/webhooks The outbound Webhooks #
POST /admin/webhooks Register one Webhook #
DELETE /admin/webhooks/{id} Remove one Webhook #
GET /admin/video/jobs The social video jobs, newest first. #
POST /admin/video/jobs Create a social video draft that waits for the owner. #
PATCH /admin/video/jobs/{id} Approve, schedule, cancel or kill a video job. #
GET /admin/video/queue The publish queue: due jobs, the kill switch and spend against the caps. #
GET /admin/voice The voice-agent settings the call path uses, and whether a stored override or… #
PUT /admin/voice Replace the stored voice-agent settings row; the schema must pass. #
DELETE /admin/voice Remove the stored voice-agent settings so the site config defaults apply again. #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/dishdirectory-com:dishdirectory-com-admin-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

dishdirectory-com-admin-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Dish Directory Admin API
  version: '1'
  description: The read API is free, needs no key and reads only. The admin routes under /admin/ need an admin session. Every read response carries `meta.attribution` and `meta.sources`.
servers:
- url: https://dishdirectory.com/api/v1
tags:


# --- truncated at 32 KB (732 KB total) ---
# Full source: https://artifacts.apis.io/dishdirectory-com/openapi/dishdirectory-com-admin-api-openapi.yml