EpicDirectories orders (admin) API

The orders (admin) API from EpicDirectories — 2 operation(s) for orders (admin).

Operations 4

GET /v1/directories/{directoryId}/orders List content orders for a directory #
POST /v1/directories/{directoryId}/orders Record a comped order — work promised without a payment #
GET /v1/directories/{directoryId}/orders/{orderId} Get one content order #
PATCH /v1/directories/{directoryId}/orders/{orderId} Advance an order, record where it was published, or leave a note #

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/epicdirectories:epicdirectories-orders-admin-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

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

epicdirectories-orders-admin-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: EpicDirectories orders (admin) API
  description: API-first directory data platform.
  version: '1.0'
  contact: {}
servers:
- url: https://api.epicdirectories.com
  description: Production
- url: http://localhost:3333
  description: Local development
tags:
- name: orders (admin)
paths:
  /v1/directories/{directoryId}/orders:
    get:
      operationId: OrdersOperatorController_list
      summary: List content orders for a directory
      description: 'Rows newest first, each with the payment that bought it (amount, currency and — the one worth noticing before doing a day of work — whether it has since been refunded).


        Also returns `countsByStatus` across the whole directory and `openCount`, the number still awaiting work. A comped order has `payment: null`, which is not a missing row.


        `status=open` is a filter alias for `received` or `in_progress` — no row holds that value; it is the answer to "what needs work", which spans two stored statuses.'
      parameters:
      - name: directoryId
        required: true
        in: path
        schema:
          type: string
      - name: status
        required: false
        in: query
        description: Omit for every status. `open` is a FILTER ALIAS, not a stored value — it means `received` or `in_progress`, which is the answer to "what needs work". It is what the queue page asks for by default, and `openCount` in the response is its size.
        schema:
          enum:
          - open
          - received
          - in_progress
          - delivered
          - cancelled
          - refunded
          type: string
      - name: kind
        required: false
        in: query
        schema:
          enum:
          - guest_post
          - niche_edit
          type: string
      - name: limit
        required: false
        in: query
        description: Default 50, max 200
        schema:
          type: string
      - name: offset
        required: false
        in: query
        schema:
          type: string
      responses:
        '200':
          description: Paginated orders, counts by status, and openCount
        '404':
          description: Directory not found or not yours
      tags:
      - orders (admin)
      security:
      - bearer: []
    post:
      operationId: OrdersOperatorController_createComped
      summary: Record a comped order — work promised without a payment
      description: 'The comp path, and the same argument as granting a boost by hand: comping is real, and the alternative is writing a fake Payment row to make the queue look right, which would corrupt the one table that reconciles against Stripe. So this creates **no Payment row** and the order''s `paymentId` stays null.


        Every field but `kind` is optional. An operator arranging a guest post over email may have only an address at this point, and refusing the row until the brief is complete is how the order ends up not recorded at all.


        Fires `order.received`, with the same keys a paid order sends and nulls where the payment would have been.'
      parameters:
      - name: directoryId
        required: true
        in: path
        schema:
          type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCompedOrderDto'
      responses:
        '201':
          description: The created order
        '400':
          description: kind was not guest_post or niche_edit
        '404':
          description: Directory not found or not yours
      tags:
      - orders (admin)
      security:
      - bearer: []
  /v1/directories/{directoryId}/orders/{orderId}:
    get:
      operationId: OrdersOperatorController_get
      summary: Get one content order
      description: 'Includes the buyer''s brief. Treat every buyer-supplied field as untrusted text: it is whatever was typed into a Stripe custom field, and `targetUrl` rendered straight into an `href` turns a purchase into a stored redirect.'
      parameters:
      - name: directoryId
        required: true
        in: path
        schema:
          type: string
      - name: orderId
        required: true
        in: path
        schema:
          type: string
      responses:
        '200':
          description: The order
        '404':
          description: Order not found in this directory
      tags:
      - orders (admin)
      security:
      - bearer: []
    patch:
      operationId: OrdersOperatorController_update
      summary: Advance an order, record where it was published, or leave a note
      description: 'Send any of `status`, `placementUrl`, `operatorNotes`. An empty body is a 400 rather than a no-op.


        **`delivered` requires a `placementUrl`**, already stored or sent in the same request. The rule is checked against the resulting state, so clearing the URL of a delivered order is refused as well.


        **`refunded` cannot be set by hand, and an order already refunded answers 409 to any status change.** A refund is Stripe''s fact, arriving over the signed webhook. If the work was done anyway, record the placement URL and a note — that says what happened without overwriting the fact that the money went back.


        Reaching `delivered` for the first time fires `order.delivered`. Later edits to a delivered order do not re-fire it, and do not move `deliveredAt`.'
      parameters:
      - name: directoryId
        required: true
        in: path
        schema:
          type: string
      - name: orderId
        required: true
        in: path
        schema:
          type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateOrderDto'
      responses:
        '200':
          description: The updated order
        '400':
          description: Empty body, an unsettable status, a placementUrl that is not an https URL, or `delivered` without one
        '404':
          description: Order not found in this directory
        '409':
          description: The order was refunded; its status is fixed
      tags:
      - orders (admin)
      security:
      - bearer: []
components:
  schemas:
    UpdateOrderDto:
      type: object
      properties:
        status:
          type: string
          enum:
          - received
          - in_progress
          - delivered
          - cancelled
          description: '`refunded` is deliberately not accepted. A refund is Stripe''s fact and arrives over the signed webhook, which sets it; a status typed here could claim money went back when it did not. An order already refunded answers 409 to any status change.'
        placementUrl:
          type: string
          description: Where it was published. **Required in order to reach `delivered`** — it is the only field that lets anyone but the operator confirm the buyer got what they paid for. Send an empty string to clear it, which is refused while the order is delivered.
        operatorNotes:
          type: string
          description: Operator-only. Never rendered publicly. Empty string clears it.
    CreateCompedOrderDto:
      type: object
      properties:
        kind:
          type: string
          enum:
          - guest_post
          - niche_edit
        purchaserEmail:
          type: string
          description: 'Who the work is discussed with. Not validated as an email: this is a note to the operator, and nothing sends mail to it — there is no email infrastructure in this system.'
        targetUrl:
          type: string
          description: Link destination the post should point at.
        anchorText:
          type: string
        brief:
          type: string
          description: Topic, a link to a draft, or instructions.
        operatorNotes:
          type: string
          description: Why it was comped, ideally.
      required:
      - kind
  securitySchemes:
    bearer:
      scheme: bearer
      bearerFormat: JWT
      type: http
    apiKey:
      type: apiKey
      in: header
      name: x-api-key