{
  "openapi": "3.1.0",
  "info": {
    "title": "DexPaprika Web API",
    "summary": "HTTP endpoints of the dexpaprika.com web app",
    "description": "Server-side endpoints that power the dexpaprika.com web experience. Most of them are reserved for the site's own renderer and answer HTTP 403 to outside callers; each operation below says which. For the public DexPaprika REST API (chains, pools, tokens, OHLCV, transactions across all 35 networks) use https://api.dexpaprika.com, documented at https://docs.dexpaprika.com/introduction. For live streaming use https://streaming.dexpaprika.com/sse/prices.\n\nAll dexpaprika.com pages also support content negotiation: send `Accept: text/markdown` to receive a Markdown version of any page instead of HTML.\n\nVersioning and deprecation policy: the response contract is identified by a dated version string, currently 2026-08-24. Send it in the X-API-Version request header to pin the contract; omit the header to track the current version. Every data response echoes the version it was produced under in the X-API-Version response header. A breaking change ships as a new dated version, never as a mutation of an existing one. When an endpoint or a version is retired it first carries the RFC 9745 Deprecation header and the RFC 8594 Sunset header, with a Link rel=\"deprecation\" pointing at the migration note. Sunset is never set less than six months after Deprecation, so an agent that reads these headers always has at least six months to migrate.",
    "version": "1.1.0",
    "contact": {
      "name": "CoinPaprika sp. z o.o.",
      "email": "contact@coinpaprika.com",
      "url": "https://coinpaprika.com"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://dexpaprika.com/terms"
    }
  },
  "servers": [
    {
      "url": "https://dexpaprika.com",
      "description": "Web app (this spec)"
    },
    {
      "url": "https://api.dexpaprika.com",
      "description": "Public REST API (separate spec at docs.dexpaprika.com)"
    }
  ],
  "externalDocs": {
    "description": "Public DexPaprika API reference (all chains, pools, tokens, transactions)",
    "url": "https://docs.dexpaprika.com/introduction"
  },
  "tags": [
    {
      "name": "Bootstrap",
      "description": "Bulk data for initial page render"
    },
    {
      "name": "Networks",
      "description": "Chain and DEX discovery"
    },
    {
      "name": "Search",
      "description": "Full-text search across pools and tokens"
    },
    {
      "name": "Streaming",
      "description": "Real-time SSE token price streams"
    },
    {
      "name": "Submissions",
      "description": "User submissions for new chains and tokens"
    }
  ],
  "paths": {
    "/api/bootstrap/{network}": {
      "get": {
        "tags": [
          "Bootstrap"
        ],
        "operationId": "getBootstrap",
        "summary": "Bulk initial data for a chain page",
        "description": "Returns stats, all networks, DEXes for the chain, and the chain's own summary, the one call that hydrates a chain or home page. Reserved for the site renderer: outside callers receive HTTP 403. The public equivalent is https://api.dexpaprika.com/networks combined with https://api.dexpaprika.com/stats.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ApiVersion"
          },
          {
            "name": "network",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Chain identifier (e.g. `ethereum`, `solana`, `base`)"
          }
        ],
        "responses": {
          "200": {
            "description": "Bootstrap payload",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BootstrapResponse"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/X-API-Version"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "403": {
            "description": "Reserved for the site renderer. Use https://api.dexpaprika.com for public access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "about:blank",
                  "title": "Forbidden",
                  "status": 403,
                  "detail": "This endpoint is reserved for the dexpaprika.com renderer. Use https://api.dexpaprika.com.",
                  "instance": "/api/networks",
                  "code": "forbidden"
                }
              }
            }
          },
          "404": {
            "description": "No such resource. Page URLs answer with a short Markdown body for clients that do not ask for HTML.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Not Found",
                  "status": 404,
                  "instance": "/api/bootstrap/nosuchchain",
                  "code": "not_found"
                }
              }
            }
          },
          "429": {
            "description": "Request rate or upstream call budget exceeded. Honour Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Too Many Requests",
                  "status": 429,
                  "instance": "/api/search",
                  "code": "rate_limited"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected failure, or an upstream dependency is unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Present when the failure is known to be transient.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Service Unavailable",
                  "status": 503,
                  "instance": "/api/stats",
                  "code": "upstream_unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/api/networks": {
      "get": {
        "tags": [
          "Networks"
        ],
        "operationId": "listNetworks",
        "summary": "List all supported blockchain networks",
        "responses": {
          "200": {
            "description": "Array of Network objects",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Network"
                  }
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/X-API-Version"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "403": {
            "description": "Reserved for the site renderer. Use https://api.dexpaprika.com for public access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "about:blank",
                  "title": "Forbidden",
                  "status": 403,
                  "detail": "This endpoint is reserved for the dexpaprika.com renderer. Use https://api.dexpaprika.com.",
                  "instance": "/api/networks",
                  "code": "forbidden"
                }
              }
            }
          },
          "429": {
            "description": "Request rate or upstream call budget exceeded. Honour Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Too Many Requests",
                  "status": 429,
                  "instance": "/api/search",
                  "code": "rate_limited"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected failure, or an upstream dependency is unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Present when the failure is known to be transient.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Service Unavailable",
                  "status": 503,
                  "instance": "/api/stats",
                  "code": "upstream_unavailable"
                }
              }
            }
          }
        },
        "description": "List all supported blockchain networks. Reserved for the site renderer: outside callers receive HTTP 403. The public equivalent is https://api.dexpaprika.com/networks.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ApiVersion"
          }
        ]
      }
    },
    "/api/stats": {
      "get": {
        "tags": [
          "Networks"
        ],
        "operationId": "getStats",
        "summary": "Platform-wide aggregate statistics",
        "responses": {
          "200": {
            "description": "Chain, DEX, token and pool totals",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Stats"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/X-API-Version"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "403": {
            "description": "Reserved for the site renderer. Use https://api.dexpaprika.com for public access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "about:blank",
                  "title": "Forbidden",
                  "status": 403,
                  "detail": "This endpoint is reserved for the dexpaprika.com renderer. Use https://api.dexpaprika.com.",
                  "instance": "/api/networks",
                  "code": "forbidden"
                }
              }
            }
          },
          "429": {
            "description": "Request rate or upstream call budget exceeded. Honour Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Too Many Requests",
                  "status": 429,
                  "instance": "/api/search",
                  "code": "rate_limited"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected failure, or an upstream dependency is unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Present when the failure is known to be transient.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Service Unavailable",
                  "status": 503,
                  "instance": "/api/stats",
                  "code": "upstream_unavailable"
                }
              }
            }
          }
        },
        "description": "Platform-wide aggregate statistics. Reserved for the site renderer: outside callers receive HTTP 403. The public equivalent is https://api.dexpaprika.com/stats.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ApiVersion"
          }
        ]
      }
    },
    "/api/search": {
      "get": {
        "tags": [
          "Search"
        ],
        "operationId": "search",
        "summary": "Search pools, tokens, and networks",
        "parameters": [
          {
            "$ref": "#/components/parameters/ApiVersion"
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "Free-text query: token symbol, name, or on-chain address"
          }
        ],
        "responses": {
          "200": {
            "description": "Grouped search results",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/X-API-Version"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "403": {
            "description": "Reserved for the site renderer. Use https://api.dexpaprika.com for public access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "about:blank",
                  "title": "Forbidden",
                  "status": 403,
                  "detail": "This endpoint is reserved for the dexpaprika.com renderer. Use https://api.dexpaprika.com.",
                  "instance": "/api/networks",
                  "code": "forbidden"
                }
              }
            }
          },
          "429": {
            "description": "Request rate or upstream call budget exceeded. Honour Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Too Many Requests",
                  "status": 429,
                  "instance": "/api/search",
                  "code": "rate_limited"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected failure, or an upstream dependency is unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Present when the failure is known to be transient.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Service Unavailable",
                  "status": 503,
                  "instance": "/api/stats",
                  "code": "upstream_unavailable"
                }
              }
            }
          }
        },
        "description": "Search pools, tokens, and networks. Reserved for the site renderer: outside callers receive HTTP 403. The public equivalent is https://api.dexpaprika.com/search, which spells the parameter `query` rather than `q` and rejects `q` with HTTP 400."
      }
    },
    "/api/submit": {
      "post": {
        "tags": [
          "Submissions"
        ],
        "operationId": "submitAsset",
        "summary": "Submit a pool/token for review",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Submission received",
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/X-API-Version"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "403": {
            "description": "Reserved for the site renderer. Use https://api.dexpaprika.com for public access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "about:blank",
                  "title": "Forbidden",
                  "status": 403,
                  "detail": "This endpoint is reserved for the dexpaprika.com renderer. Use https://api.dexpaprika.com.",
                  "instance": "/api/networks",
                  "code": "forbidden"
                }
              }
            }
          },
          "429": {
            "description": "Request rate or upstream call budget exceeded. Honour Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Too Many Requests",
                  "status": 429,
                  "instance": "/api/search",
                  "code": "rate_limited"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected failure, or an upstream dependency is unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Present when the failure is known to be transient.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Service Unavailable",
                  "status": 503,
                  "instance": "/api/stats",
                  "code": "upstream_unavailable"
                }
              }
            }
          }
        },
        "description": "Submit a pool or token for review. Reserved for the site renderer: outside callers receive HTTP 403. The public equivalent is the form at https://dexpaprika.com/add-asset.",
        "parameters": [
          {
            "$ref": "#/components/parameters/ApiVersion"
          }
        ]
      }
    },
    "/api/streaming/{chainId}/tokens": {
      "get": {
        "tags": [
          "Streaming"
        ],
        "operationId": "streamTokens",
        "summary": "Streaming token list for a chain",
        "parameters": [
          {
            "$ref": "#/components/parameters/ApiVersion"
          },
          {
            "name": "chainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Token list for the chain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamingTokens"
                }
              }
            },
            "headers": {
              "X-API-Version": {
                "$ref": "#/components/headers/X-API-Version"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "404": {
            "description": "No such resource. Page URLs answer with a short Markdown body for clients that do not ask for HTML.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Not Found",
                  "status": 404,
                  "instance": "/api/bootstrap/nosuchchain",
                  "code": "not_found"
                }
              }
            }
          },
          "429": {
            "description": "Request rate or upstream call budget exceeded. Honour Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Too Many Requests",
                  "status": 429,
                  "instance": "/api/search",
                  "code": "rate_limited"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected failure, or an upstream dependency is unavailable.",
            "headers": {
              "Retry-After": {
                "description": "Present when the failure is known to be transient.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "title": "Service Unavailable",
                  "status": 503,
                  "instance": "/api/stats",
                  "code": "upstream_unavailable"
                }
              }
            }
          }
        },
        "description": "JSON list of the tokens the /streaming/{chainId} demo page subscribes to. This is a plain JSON document, not an event stream. The live SSE feed is POST https://streaming.dexpaprika.com/sse/prices (or GET with `chain`, `address` and `method=token_price`), which emits `event: token_price` when a swap moves the price."
      }
    }
  },
  "components": {
    "schemas": {
      "Stats": {
        "type": "object",
        "properties": {
          "chains": {
            "type": "integer",
            "description": "Supported blockchain networks",
            "example": 36
          },
          "factories": {
            "type": "integer",
            "description": "DEX factory contracts tracked. The upstream field is `factories`, not `dexes`.",
            "example": 234
          },
          "pools": {
            "type": "integer",
            "example": 37704116
          },
          "tokens": {
            "type": "integer",
            "example": 34766839
          }
        },
        "required": [
          "chains",
          "pools",
          "tokens"
        ]
      },
      "Network": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "ethereum"
          },
          "display_name": {
            "type": "string",
            "example": "Ethereum"
          },
          "pools_count": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "display_name"
        ]
      },
      "Dex": {
        "type": "object",
        "properties": {
          "dex_id": {
            "type": "string",
            "example": "uniswap_v3"
          },
          "dex_name": {
            "type": "string",
            "example": "Uniswap V3"
          },
          "chain": {
            "type": "string",
            "example": "ethereum"
          }
        }
      },
      "BootstrapResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/Stats"
          },
          "networks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Network"
            }
          },
          "dexes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Dex"
            }
          },
          "network": {
            "$ref": "#/components/schemas/Network"
          }
        }
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "networks": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "pools": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "tokens": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "SubmitRequest": {
        "type": "object",
        "required": [
          "email",
          "address"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "address": {
            "type": "string",
            "description": "Token or pool contract address"
          },
          "chain": {
            "type": "string"
          },
          "notes": {
            "type": "string"
          }
        }
      },
      "StreamingTokens": {
        "type": "object",
        "properties": {
          "chain": {
            "type": "string",
            "example": "solana"
          },
          "chainDisplayName": {
            "type": "string",
            "example": "Solana"
          },
          "chainColor": {
            "type": "string",
            "example": "#9945FF"
          },
          "tokens": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "address": {
                  "type": "string"
                },
                "symbol": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          }
        },
        "required": [
          "chain",
          "tokens"
        ]
      },
      "Problem": {
        "type": "object",
        "description": "Error body returned by every 4xx and 5xx response. RFC 9457 problem-details shape, extended with a stable machine-readable `code` and with the legacy `statusCode` / `statusMessage` fields this site has always emitted, so existing clients keep working. Branch on `code`, never on `title` or `detail`.",
        "required": [
          "status",
          "title",
          "code"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "URI identifying the problem type.",
            "default": "about:blank"
          },
          "title": {
            "type": "string",
            "description": "Short, human-readable summary. Stable for a given `code`.",
            "example": "Forbidden"
          },
          "status": {
            "type": "integer",
            "minimum": 400,
            "maximum": 599,
            "description": "HTTP status code, repeated in the body.",
            "example": 403
          },
          "detail": {
            "type": "string",
            "description": "Human-readable explanation specific to this occurrence.",
            "example": "This endpoint is reserved for the site renderer. Use https://api.dexpaprika.com."
          },
          "instance": {
            "type": "string",
            "format": "uri-reference",
            "description": "The request path that produced the error.",
            "example": "/api/networks"
          },
          "code": {
            "type": "string",
            "description": "Stable machine-readable error code. Safe to branch on.",
            "enum": [
              "forbidden",
              "not_found",
              "rate_limited",
              "upstream_unavailable",
              "upstream_budget_exceeded",
              "invalid_request",
              "internal_error"
            ],
            "example": "forbidden"
          },
          "statusCode": {
            "type": "integer",
            "deprecated": true,
            "description": "Legacy alias of `status`. Retained for existing clients; prefer `status`."
          },
          "statusMessage": {
            "type": "string",
            "deprecated": true,
            "description": "Legacy alias of `title`. Retained for existing clients; prefer `title`."
          }
        }
      }
    },
    "parameters": {
      "ApiVersion": {
        "name": "X-API-Version",
        "in": "header",
        "required": false,
        "description": "Pin the response contract to a dated version. Omit to receive the current version, which is echoed back in the X-API-Version response header. An unknown value is ignored, never rejected.",
        "schema": {
          "type": "string",
          "enum": [
            "2026-08-24"
          ],
          "default": "2026-08-24"
        }
      }
    },
    "headers": {
      "X-API-Version": {
        "description": "The contract version that produced this response. Always present on data endpoints.",
        "schema": {
          "type": "string",
          "example": "2026-08-24"
        }
      },
      "Deprecation": {
        "description": "RFC 9745. Present once an endpoint is deprecated; an IMF-fixdate for the moment deprecation took effect.",
        "schema": {
          "type": "string",
          "example": "Wed, 24 Feb 2027 00:00:00 GMT"
        }
      },
      "Sunset": {
        "description": "RFC 8594. The date after which the endpoint may stop responding. Never less than six months after the matching Deprecation date.",
        "schema": {
          "type": "string",
          "example": "Tue, 24 Aug 2027 00:00:00 GMT"
        }
      }
    }
  }
}
