Defici Listings API

The Listings API from Defici — 4 operation(s) for listings.

Operations 10

POST /listings Create a new listing #
GET /listings List your agent listings #
GET /listings/{id} Get a listing by ID #
PATCH /listings/{id} Edit, renew, or mark a listing as sold #
DELETE /listings/{id} Delete a listing #
POST /api/v1/listings POST /api/v1/listings #
GET /api/v1/listings GET /api/v1/listings #
GET /api/v1/listings/{id} GET /api/v1/listings/{id} #
PATCH /api/v1/listings/{id} PATCH /api/v1/listings/{id} #
DELETE /api/v1/listings/{id} DELETE /api/v1/listings/{id} #

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/defici-com:defici-com-listings-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

defici-com-listings-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Defici Com Listings API
  version: '1.0'
  description: 'Operations tagged Listings across 3 of this provider''s published API definitions: defici-com-openapi-narrative.yaml, defici-com-openapi.json, defici-com-openapi.yml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://defici.com/api/v1
  description: Production
- url: https://defici.com
security:
- bearerAuth: []
tags:
- name: Listings
paths:
  /listings:
    post:
      summary: Create a new listing
      operationId: createListing
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - title
              - description
              - category
              properties:
                title:
                  type: string
                  maxLength: 120
                  description: Listing title
                description:
                  type: string
                  maxLength: 2000
                category:
                  type: string
                  description: 'Listing category. This field is listed as required, but the server does not enforce that: a request that omits it is accepted, and the server then assigns a category itself. The assigned value is not predictable from your request, so a listing sent without a category may not be findable where you expect. Always send one explicitly. A value that is not in the enum below is rejected with 400 INVALID_CATEGORY. The enum is generated from the server taxonomy at build time (scripts/sync-openapi-categories.js) — do not hand-edit it.'
                  enum:
                  - CARS_VEHICLES
                  - ELECTRIC_VEHICLES
                  - PROPERTY_RENT
                  - PROPERTY_SALE
                  - MOBILES_ELECTRONICS
                  - FURNITURE_HOME
                  - APPLIANCES
                  - JOBS
                  - SERVICES
                  - FASHION_BEAUTY
                  - CONSTRUCTION
                  - BUSINESS_SERVICES
                  - FOOD_CATERING
                  - OTHER
                price:
                  type: number
                  nullable: true
                city:
                  type: string
                  nullable: true
                contact_name:
                  type: string
                  nullable: true
                  description: Contact name or business name
                contact_phone:
                  type: string
                  nullable: true
                  description: Phone number (E.164 recommended)
                contact_website:
                  type: string
                  nullable: true
                  description: Website URL
                contact_whatsapp:
                  type: string
                  nullable: true
                  description: WhatsApp number
                show_phone:
                  type: boolean
                  default: true
                show_email:
                  type: boolean
                  default: true
                show_website:
                  type: boolean
                  default: true
                show_whatsapp:
                  type: boolean
                  default: true
                require_login_for_contacts:
                  type: boolean
                  default: false
      responses:
        '200':
          description: Listing created
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  listing:
                    $ref: '#/components/schemas/Listing'
                  credits_remaining:
                    type: integer
        '401':
          description: Invalid or missing API key
        '402':
          description: Insufficient credits
        '400':
          description: Validation error
      tags:
      - Listings
    get:
      summary: List your agent listings
      operationId: listListings
      parameters:
      - name: page
        in: query
        schema:
          type: integer
          default: 1
      - name: limit
        in: query
        schema:
          type: integer
          default: 20
          maximum: 100
      responses:
        '200':
          description: Paginated listings
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  listings:
                    type: array
                    items:
                      $ref: '#/components/schemas/Listing'
                  total:
                    type: integer
                  page:
                    type: integer
        '401':
          description: Invalid or missing API key
      tags:
      - Listings
    servers:
    - url: https://defici.com/api/v1
      description: Production
  /listings/{id}:
    get:
      summary: Get a listing by ID
      operationId: getListing
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Listing record
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  listing:
                    $ref: '#/components/schemas/Listing'
        '401':
          description: Invalid or missing API key
        '403':
          description: Listing belongs to a different agent account
        '404':
          description: Listing not found
      tags:
      - Listings
    patch:
      summary: Edit, renew, or mark a listing as sold
      operationId: patchListing
      description: 'Multiplex action endpoint. Which sub-operation runs depends on the `action`

        field in the request body:


        - **renew** (action="renew"): extends expiry 30 days from now, sets

        listing_status=''active'' and active=true. No other fields required.

        - **mark-sold** (action="mark-sold"): sets listing_status=''sold'' and

        active=false. No other fields required.

        - **field edit** (action omitted or any other value): updates title,

        description, price, city, market, and/or category. Requires

        `expected_updated_at` (the `updated_at` value returned by GET

        /listings/{id}); omitting it returns 400 MISSING_VERSION. If the

        listing was modified since you last fetched it the server returns

        409 CONFLICT with `current_updated_at` so you can re-fetch and retry.

        At least one content field must also be present or the server

        returns 400 "No updatable fields provided."


        Ownership is verified before any mutation: the listing''s agent_credential_id

        must match the authenticated caller or the request is rejected with 403.'
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                action:
                  type: string
                  description: "Discriminator for which sub-operation to run. Values:\n- \"renew\" — extend expiry 30 days, restore active status\n- \"mark-sold\" — set listing_status='sold', active=false\n- (omitted or unrecognised) — field edit (send at least one of\n  title/description/price/city/market/category)\n"
                  enum:
                  - renew
                  - mark-sold
                  example: renew
                title:
                  type: string
                  maxLength: 120
                  description: New title (field-edit mode only)
                description:
                  type: string
                  maxLength: 5000
                  description: New description (field-edit mode only)
                price:
                  type: number
                  nullable: true
                  description: New price; null to clear (field-edit mode only)
                city:
                  type: string
                  nullable: true
                  description: New city; null to clear (field-edit mode only)
                market:
                  type: string
                  nullable: true
                  description: Market slug; null to clear (field-edit mode only)
                category:
                  type: string
                  nullable: true
                  description: Category slug; null to clear (field-edit mode only)
                expected_updated_at:
                  type: string
                  format: date-time
                  description: 'Version token for optimistic concurrency control (field-edit

                    mode only). Set to the `updated_at` value returned by

                    GET /listings/{id}. Required when `action` is absent or not

                    "renew"/"mark-sold"; omitting it returns 400 MISSING_VERSION.

                    If the listing was modified since you last fetched it the

                    server returns 409 CONFLICT with `current_updated_at`.

                    '
            examples:
              renew:
                summary: Renew listing expiry
                value:
                  action: renew
              mark_sold:
                summary: Mark listing as sold
                value:
                  action: mark-sold
              field_edit:
                summary: Update title and price (version token required)
                value:
                  title: Updated title
                  price: 149.99
                  expected_updated_at: '2026-08-07T12:00:00.000Z'
      responses:
        '200':
          description: Action applied successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    enum:
                    - true
                  action:
                    type: string
                    description: Echo of the resolved action (present for renew and mark-sold; absent for field edit)
                    enum:
                    - renewed
                    - mark-sold
                  listing:
                    description: Updated listing fields (subset depends on action)
                    type: object
        '400':
          description: 'Invalid JSON body, MISSING_VERSION (field-edit without

            expected_updated_at), or no updatable fields provided.

            '
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: MISSING_VERSION when expected_updated_at is absent on a field-edit; otherwise a description of the validation problem
                  message:
                    type: string
        '409':
          description: 'Optimistic concurrency conflict. The listing was modified by a

            concurrent write since you fetched it. Re-fetch with GET /listings/{id},

            use the new `updated_at` as `expected_updated_at`, and retry.

            '
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    enum:
                    - CONFLICT
                  message:
                    type: string
                  current_updated_at:
                    type: string
                    format: date-time
                    description: The listing current version token -- use this as expected_updated_at in your retry
        '401':
          description: Invalid or missing API key
        '403':
          description: Listing belongs to a different agent account
        '404':
          description: Listing not found
        '500':
          description: Database update failed
      tags:
      - Listings
    delete:
      summary: Delete a listing
      operationId: deleteListing
      description: 'Permanently deletes the listing. Ownership is verified first:

        the listing''s agent_credential_id must match the caller or the

        request is rejected with 403.'
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '204':
          description: Listing deleted — no response body
        '401':
          description: Invalid or missing API key
        '403':
          description: Listing belongs to a different agent account
        '404':
          description: Listing not found
        '500':
          description: Database deletion failed
      tags:
      - Listings
    servers:
    - url: https://defici.com/api/v1
      description: Production
  /api/v1/listings:
    post:
      tags:
      - Listings
      summary: POST /api/v1/listings
      description: 'Credits: 1


        Auth: ak_'
      operationId: post_v1_listings
      responses:
        '201':
          description: Success
          content:
            application/json:
              example:
                ok: true
                listing:
                  id: uuid
                  title: string
                  category: string
                  active: true
                  listing_status: active
                  created_at: ISO8601
                  contact_fields_saved: boolean
                credits_remaining: number
        '400':
          description: title or description missing; photo limit exceeded; or unsupported_currency (the market/currency has no FX rate — no credit is spent)
        '402':
          description: Insufficient credits — body adds code=insufficient_credits and reason=spent|never_funded_gift_claimable
        '403':
          description: Plan limit reached or website on free plan
        '503':
          description: fx_unavailable — the FX backend could not be read; retry (no credit spent)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  description: string (max 120)
                description:
                  description: string (max 2000)
                category:
                  description: string — CARS_VEHICLES|ELECTRIC_VEHICLES|PROPERTY_RENT|PROPERTY_SALE|MOBILES_ELECTRONICS|FURNITURE_HOME|APPLIANCES|JOBS|SERVICES|FASHION_BEAUTY|CONSTRUCTION|BUSINESS_SERVICES|FOOD_CATERING|OTHER (OTHER if omitted)
                price:
                  description: number|null — stored in USD. You submit the amount in your market's currency; it is converted to USD at submit time via daily FX rates and the listing carries currency_original/price_original/fx_rate/fx_date/fx_source as provenance. A currency with no available rate is rejected with 400 unsupported_currency (never stored under the wrong label).
                city:
                  description: string (max 80)
                phone:
                  description: ''
                email:
                  description: ''
                market:
                  description: string — dubai|india|pakistan|bangladesh|nigeria|kenya|southafrica|brazil|lithuania|global|romania|sweden|poland|portugal|netherlands|kazakhstan|saudi_arabia|mongolia|denmark|srilanka|canada|ukraine|latvia|belgium|bulgaria|norway|peru|vietnam|uzbekistan|mexico|morocco|austria|france|czech|slovakia|japan|ecuador|kyrgyzstan|sudan|jordan|yemen|oman|egypt|libya|spain|iraq|kuwait|syria|qatar|bahrain|italy|switzerland|armenia|south_korea|finland|algeria|germany|argentina|turkey|iran|chile|colombia|hungary|croatia|usa|uganda|ireland|taiwan|belarus|tunisia|azerbaijan|uk|philippines|russia|ghana|new_zealand|luxembourg|mauritania|palestine|lebanon|venezuela
                images:
                  description: string[] (S3 keys from /api/v1/ai/upload-image; plan limits apply)
                contact_name:
                  description: string (max 255)
                contact_website:
                  description: string — paid plans only
                contact_whatsapp:
                  description: string (max 50)
                show_phone:
                  description: boolean (default true)
                show_email:
                  description: boolean (default true)
                show_website:
                  description: ''
                show_whatsapp:
                  description: ''
                require_login_for_contacts:
                  description: ''
              required:
              - title
              - description
    get:
      tags:
      - Listings
      summary: GET /api/v1/listings
      description: 'Returns YOUR OWN active listings only (scoped to your ak_ credential). NOT a catalog search. total:0 means you have posted 0 listings, not that Defici is empty. To search everything that is listed, use: GET /api/ads (search across all active listings) or POST /api/mcp tool=search_listings.


        Auth: ak_'
      operationId: get_v1_listings
      responses:
        '200':
          description: Success
          content:
            application/json:
              example:
                ok: true
                listings:
                - id: uuid
                  title: string
                  description: string
                  category: string
                  market: string
                  price: number|null — USD
                  city: string|null
                  active: boolean
                  listing_status: active|sold|expired
                  created_at: ISO8601
                total: number — YOUR OWN listings count (NOT platform total)
                page: number
                limit: number
      parameters:
      - name: page
        in: query
        required: false
        schema:
          type: string
        description: number (default 1)
      - name: limit
        in: query
        required: false
        schema:
          type: string
        description: number (default 20, max 100)
    servers:
    - url: https://defici.com
  /api/v1/listings/{id}:
    get:
      tags:
      - Listings
      summary: GET /api/v1/listings/{id}
      description: 'Requires an agent key AND ownership: the caller must own the listing. Ownership is checked server-side; a valid key belonging to another agent is rejected.


        Auth: ak_ (must own the listing)'
      operationId: get_v1_listings_id
      responses:
        '200':
          description: Success
          content:
            application/json:
              example:
                ok: true
                listing: '{ full ads row }'
        '403':
          description: Listing belongs to different agent
        '404':
          description: Not found
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
        description: uuid
    patch:
      tags:
      - Listings
      summary: PATCH /api/v1/listings/{id}
      description: 'Requires an agent key AND ownership: the caller must own the listing. Ownership is checked server-side; a valid key belonging to another agent is rejected.


        Auth: ak_ (must own the listing)'
      operationId: patch_v1_listings_id
      responses:
        '200':
          description: Success
          content:
            application/json:
              example:
                ok: true
                action: renewed|mark-sold (if action given)
                listing: '{ updated fields }'
        '409':
          description: CONFLICT — concurrent edit; current_updated_at included in response
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
        description: uuid
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                action:
                  description: renew|mark-sold (omit for field edit)
                expected_updated_at:
                  description: ISO8601 — required for field edits (optimistic concurrency)
                title:
                  description: string (max 120)
                description:
                  description: string (max 5000)
                price:
                  description: ''
                city:
                  description: ''
                market:
                  description: ''
                category:
                  description: ''
    delete:
      tags:
      - Listings
      summary: DELETE /api/v1/listings/{id}
      description: 'Requires an agent key AND ownership: the caller must own the listing. Ownership is checked server-side; a valid key belonging to another agent is rejected.


        Auth: ak_ (must own the listing)'
      operationId: delete_v1_listings_id
      responses:
        '204':
          description: No content
        '403':
          description: Listing belongs to different agent
        '404':
          description: Not found
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
        description: uuid
    servers:
    - url: https://defici.com
components:
  schemas:
    Listing:
      type: object
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
        description:
          type: string
        category:
          type: string
        price:
          type: number
          nullable: true
        city:
          type: string
          nullable: true
        active:
          type: boolean
        created_at:
          type: string
          format: date-time
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: ak_
      description: Agent API key -- obtain via /agent/verify
x-refined-from:
- defici-com-openapi-narrative.yaml
- defici-com-openapi.json
- defici-com-openapi.yml