DeSci Labs Query API

**Research discovery and browse functionality** - Ideal for browse pages, search, and analytics. Paginated lists of research objects with optional metadata resolution, version history, and filtering capabilities.

OpenAPI Specification

desci-labs-query-api-openapi.yml Raw ↑
openapi: 3.0.0
info:
  title: dPID Resolver Data Query API
  version: 2.0.0
  description: "An open-source HTTP resolver for dPIDs, bridging decentralized protocols to HTTP for scientific research artifact data.\n\nThis API provides comprehensive endpoints to resolve dPIDs (decentralized Persistent Identifiers) to their corresponding manifests, content, and metadata. It powers both browse and detail page experiences for the decentralized research ecosystem.\n\n## Key Use Cases\n\n### Browse Pages\n- **/api/v2/query/dpids** - Paginated lists of all research objects with optional metadata\n- **Filter & sort** - Find research by recency, metadata fields, version activity  \n- **Performance optimized** - Smart caching and optional metadata resolution\n\n### Detail Pages\n- **/api/v2/resolve/dpid/{id}** - Complete research object with full version history\n- **/api/v2/resolve/{path}** - Flexible access to specific files and versions\n- **Multi-format support** - JSON, raw IPFS, MyST, JSON-LD outputs\n\n### Direct Access\n- **User-friendly URLs** - Handle dpid.org/123 style links\n- **Version navigation** - Access any historical version (v1, v2, etc.)\n- **File-level access** - Direct links to papers, data, code within research objects\n\n## Features\n- **Fast Resolution**: Resolve dPIDs to manifests and content with sub-second response times\n- **Version History**: Complete chronological access to all research object versions\n- **Metadata Enrichment**: Optional IPFS manifest resolution for titles, authors, descriptions\n- **Flexible Formats**: JSON APIs, raw IPFS redirects, MyST Markdown, JSON-LD semantic data\n- **Pagination**: Efficient browsing through large research collections\n- **Smart Caching**: Redis-backed performance optimization\n- **Cross-Protocol**: Works with both Ceramic streams and legacy blockchain contracts\n\n## Common Integration Patterns\n\n**Research Discovery Platform:**\nGET /api/v2/query/dpids?metadata=true&fields=title,authors&size=20\n\n**Research Detail View:**\nGET /api/v2/resolve/dpid/123\nGET /api/v2/resolve/123/manuscript.pdf?format=raw\n\n**Analytics Dashboard:**\nGET /api/v2/query/dpids?history=true&size=100\n\n## Authentication\nThis API is currently public and does not require authentication.\n\n## Rate Limiting\nPlease be mindful of API usage. Rate limits may be applied to prevent abuse.\n\n## Support\nQuestions? Check our GitHub Issues or contact support."
  contact:
    name: API Support
    url: https://github.com/desci-labs/dpid-resolver/issues
    email: support@desci.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
servers:
- url: /api
  description: Current Host API
- url: http://localhost:5461/api
  description: Local Development Server
- url: https://dev-beta.dpid.org/api
  description: Development API
- url: https://beta.dpid.org/api
  description: Production API
tags:
- name: Query
  description: '**Research discovery and browse functionality** - Ideal for browse pages, search, and analytics. Paginated lists of research objects with optional metadata resolution, version history, and filtering capabilities.'
paths:
  /v2/query/objects:
    get:
      tags:
      - Query
      summary: Query for all research objects
      responses:
        '200':
          description: List of research objects
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ResearchObject'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
  /v2/query/history/{id}:
    get:
      tags:
      - Query
      summary: Query for the history of a single research object
      description: 'Query the version history of a single research object using either:

        - dPID (e.g. 46)

        - stream ID (e.g. kjzl6kcym7w8y92di94io797nmzrprs5ndmcqtugbtnd27kko22fuyev08r4682)

        '
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
        description: 'Either a dPID or stream ID to query.

          Examples:

          - dPID: 46

          - stream ID: kjzl6kcym7w8y92di94io797nmzrprs5ndmcqtugbtnd27kko22fuyev08r4682

          '
      responses:
        '200':
          description: Research object history
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: Stream ID
                  owner:
                    type: string
                    description: Owner DID PKH
                  manifest:
                    type: string
                    description: Latest manifest CID
                  versions:
                    type: array
                    items:
                      $ref: '#/components/schemas/ResearchObjectHistory'
        '400':
          description: Invalid dPID or stream ID format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
        '404':
          description: dPID or stream not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
  /v2/query/history:
    post:
      tags:
      - Query
      summary: Query for the history of multiple research objects
      description: 'Query the version history of multiple research objects using a list of IDs.

        Each ID can be either a dPID or stream ID.

        '
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                ids:
                  type: array
                  items:
                    type: string
                  description: Array of dPIDs or stream IDs
                  example:
                  - '46'
                  - kjzl6kcym7w8y92di94io797nmzrprs5ndmcqtugbtnd27kko22fuyev08r4682
              required:
              - ids
      responses:
        '200':
          description: Array of research object histories
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                      description: Stream ID
                    owner:
                      type: string
                      description: Owner DID PKH
                    manifest:
                      type: string
                      description: Latest manifest CID
                    versions:
                      type: array
                      items:
                        $ref: '#/components/schemas/ResearchObjectHistory'
        '400':
          description: Invalid request body or ID format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
        '404':
          description: One or more objects not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
  /v2/query/dpids:
    get:
      tags:
      - Query
      summary: List all DPIDs with pagination, version history, and metadata
      description: 'Retrieve a paginated list of all DPIDs in the system. This endpoint is ideal for:

        - **Browse pages**: Get overview of all research objects with optional metadata

        - **Search implementations**: Paginate through DPIDs with filtering

        - **Analytics**: Understand publication patterns and volume


        ## Key Features

        - **Pagination**: Navigate through large DPID collections efficiently

        - **Optional History**: Include complete version history per DPID (`history=true`)

        - **Optional Metadata**: Resolve manifest metadata like titles, authors (`metadata=true`)

        - **Field Selection**: Choose specific metadata fields (`fields=title,authors`)

        - **Sorting**: Control order with `sort=asc|desc` (newest first by default)

        - **Smart Links**: Self-documenting pagination URLs for discovery


        ## Common Usage Patterns


        **Browse Page (Basic)**:

        ```

        GET /v2/query/dpids?page=1&size=20&metadata=true&fields=title,authors

        ```


        **Browse Page (with History)**:

        ```

        GET /v2/query/dpids?page=1&size=10&history=true&metadata=true

        ```


        **Analytics/Stats**:

        ```

        GET /v2/query/dpids?page=1&size=100&sort=asc

        ```

        '
      parameters:
      - in: query
        name: page
        schema:
          type: integer
          minimum: 1
          default: 1
        description: Page number (1-based)
      - in: query
        name: size
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
        description: Number of DPIDs per page (max 100)
      - in: query
        name: sort
        schema:
          type: string
          enum:
          - asc
          - desc
          default: desc
        description: Sort order by DPID number (desc = newest first)
      - in: query
        name: history
        schema:
          type: boolean
          default: false
        description: Include complete version history for each DPID
        example: true
      - in: query
        name: metadata
        schema:
          type: boolean
          default: false
        description: Resolve IPFS manifest metadata (authors, title, etc.)
        example: true
      - in: query
        name: fields
        schema:
          type: string
          default: title,authors
        description: 'Comma-separated metadata fields to include when metadata=true.

          Available: title, authors, description, keywords, license

          '
        example: title,authors,description
      responses:
        '200':
          description: Paginated list of DPIDs with optional history and metadata
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DpidListResponse'
              examples:
                basic:
                  summary: Basic pagination without history or metadata
                  value:
                    dpids:
                    - dpid: 557
                      owner: '0x1234567890abcdef1234567890abcdef12345678'
                      latestCid: bafkreiasyoawbtjotfckd7yi33t4rxidiqusrwj6g2hb2gsczw35nlt4we
                      versionCount: 1
                      source: ceramic
                      links:
                        history: http://localhost:5461/api/v2/query/history/557
                        latest: http://localhost:5461/api/v2/resolve/dpid/557
                        raw: http://localhost:5461/557?raw
                    pagination:
                      page: 1
                      size: 1
                      total: 557
                      hasNext: true
                      hasPrev: false
                      links:
                        self: http://localhost:5461/api/v2/query/dpids?page=1&size=1
                        first: http://localhost:5461/api/v2/query/dpids?page=1&size=1
                        next: http://localhost:5461/api/v2/query/dpids?page=2&size=1
                        last: http://localhost:5461/api/v2/query/dpids?page=557&size=1
                        withHistory: http://localhost:5461/api/v2/query/dpids?page=1&size=1&history=true
                        withMetadata: http://localhost:5461/api/v2/query/dpids?page=1&size=1&metadata=true&fields=title,authors
                withMetadata:
                  summary: With manifest metadata resolved
                  value:
                    dpids:
                    - dpid: 557
                      owner: '0x1234567890abcdef1234567890abcdef12345678'
                      latestCid: bafkreiasyoawbtjotfckd7yi33t4rxidiqusrwj6g2hb2gsczw35nlt4we
                      versionCount: 1
                      source: ceramic
                      metadata:
                        title: Sleep Duration Research Proposal
                        authors:
                        - name: John Doe
                          orcid: 0000-0000-0000-0000
                      links:
                        history: http://localhost:5461/api/v2/query/history/557
                        latest: http://localhost:5461/api/v2/resolve/dpid/557
                        raw: http://localhost:5461/557?raw
                    pagination:
                      page: 1
                      size: 1
                      total: 557
                      hasNext: true
                      hasPrev: false
                      links:
                        self: http://localhost:5461/api/v2/query/dpids?page=1&size=1&metadata=true&fields=title,authors
                        withoutMetadata: http://localhost:5461/api/v2/query/dpids?page=1&size=1
        '400':
          description: Invalid query parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
              examples:
                invalidPage:
                  summary: Invalid page parameter
                  value:
                    error: Invalid page parameter
                    details: Page must be a positive integer
                    params:
                      page: '0'
                      size: '20'
                    path: /api/v2/query/dpids
                invalidSize:
                  summary: Invalid size parameter
                  value:
                    error: Invalid size parameter
                    details: Size must be between 1 and 100
                    params:
                      page: '1'
                      size: '200'
                    path: /api/v2/query/dpids
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
  /v2/query/owner/{id}:
    get:
      tags:
      - Query
      summary: Query for research objects by owner
      description: 'Retrieve all research objects owned by a specific address. This endpoint:

        - Fetches all research objects from the system

        - Filters them by the specified owner address

        - Supports both full DID format and plain address format


        ## Owner ID Format

        The owner ID can be provided in two formats:

        - **Plain address**: `0x90b2c654f18e491a566d6a38c491cf82745e5987`

        - **Full DID**: `did:pkh:eip155:1337:0x90b2c654f18e491a566d6a38c491cf82745e5987`


        The endpoint will match both formats automatically.


        ## Use Cases

        - **User dashboards**: Display all research objects for a specific researcher

        - **Profile pages**: Show publication history for an address

        - **Analytics**: Track research output by author/institution

        '
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
        description: 'Owner address or DID to filter by.

          Examples:

          - Plain address: 0x90b2c654f18e491a566d6a38c491cf82745e5987

          - Full DID: did:pkh:eip155:1337:0x90b2c654f18e491a566d6a38c491cf82745e5987

          '
        example: '0x90b2c654f18e491a566d6a38c491cf82745e5987'
      responses:
        '200':
          description: List of research objects owned by the specified address
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ResearchObject'
              examples:
                success:
                  summary: Successful response with research objects
                  value:
                  - id: kjzl6kcym7w8y92di94io797nmzrprs5ndmcqtugbtnd27kko22fuyev08r4682
                    owner: did:pkh:eip155:1337:0x90b2c654f18e491a566d6a38c491cf82745e5987
                    manifest: bafkreiasyoawbtjotfckd7yi33t4rxidiqusrwj6g2hb2gsczw35nlt4we
                    title: Research Object Title
                  - id: kjzl6kcym7w8y8zxcv9io123nmzrprs5ndmcqtugbtnd27kko22fuyev08r9876
                    owner: did:pkh:eip155:1337:0x90b2c654f18e491a566d6a38c491cf82745e5987
                    manifest: bafkreidfg3awbtjotfckd7yi33t4rxidiqusrwj6g2hb2gsczw35nlt5ab
                    title: Another Research Object
                empty:
                  summary: No research objects found for owner
                  value: []
        '400':
          description: Invalid request - missing owner ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
              example:
                error: invalid request
                details: missing owner id in path parameter
                params: {}
                path: api/v2/queries/owner
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
              example:
                error: failed to fetch research objects
                details: flight client error
                params:
                  id: '0x90b2c654f18e491a566d6a38c491cf82745e5987'
                path: api/v2/queries/owner
  /v2/query/reverse/{id}:
    get:
      tags:
      - Query
      summary: Reverse lookup - find DPID by stream ID
      description: 'Perform a reverse lookup to find the DPID associated with a given stream ID.

        This is useful when you have a Ceramic stream ID and need to find its corresponding DPID.


        ## How It Works

        The endpoint searches through all registered DPIDs to find which one maps to the

        provided stream ID. Results are cached for improved performance on subsequent lookups.


        ## Use Cases

        - **External integrations**: Map Ceramic stream IDs back to DPIDs

        - **Data reconciliation**: Verify DPID-to-stream mappings

        - **Cross-referencing**: Find DPID when only stream ID is known


        Subsequent lookups for the same stream ID are served from cache.

        '
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
        description: 'The Ceramic stream ID to look up.

          Example: kjzl6kcym7w8y92di94io797nmzrprs5ndmcqtugbtnd27kko22fuyev08r4682

          '
        example: kjzl6kcym7w8y92di94io797nmzrprs5ndmcqtugbtnd27kko22fuyev08r4682
      responses:
        '200':
          description: DPID found for the provided stream ID
          content:
            application/json:
              schema:
                type: object
                properties:
                  dpid:
                    type: integer
                    description: The DPID number associated with this stream ID
                  streamId:
                    type: string
                    description: The stream ID that was looked up
                  links:
                    type: object
                    properties:
                      resolve:
                        type: string
                        description: URL to resolve this DPID
                      history:
                        type: string
                        description: URL to get version history for this DPID
              example:
                dpid: 46
                streamId: kjzl6kcym7w8y92di94io797nmzrprs5ndmcqtugbtnd27kko22fuyev08r4682
                links:
                  resolve: http://localhost:5461/api/v2/resolve/dpid/46
                  history: http://localhost:5461/api/v2/query/history/46
        '400':
          description: Invalid request - missing stream ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
              example:
                error: invalid request
                details: missing stream ID in path parameter
                params: {}
                path: api/v2/queries/reverseLookup
        '404':
          description: No DPID found for the provided stream ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
              example:
                error: not found
                details: 'no DPID found for stream ID: kjzl6kcym7w8y92di94io797nmzrprs5ndmcqtugbtnd27kko22fuyev08r4682'
                params:
                  id: kjzl6kcym7w8y92di94io797nmzrprs5ndmcqtugbtnd27kko22fuyev08r4682
                path: api/v2/queries/reverseLookup
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchObjectQueryError'
components:
  schemas:
    DpidListResponse:
      type: object
      properties:
        dpids:
          type: array
          items:
            $ref: '#/components/schemas/DpidQueryResult'
          description: Array of DPID results
        pagination:
          type: object
          properties:
            page:
              type: integer
              description: Current page number
            size:
              type: integer
              description: Number of results per page
            total:
              type: integer
              description: Total number of DPIDs
            hasNext:
              type: boolean
              description: Whether there are more pages
            hasPrev:
              type: boolean
              description: Whether there are previous pages
            links:
              type: object
              properties:
                self:
                  type: string
                  description: Current page URL
                first:
                  type: string
                  description: First page URL
                prev:
                  type: string
                  nullable: true
                  description: Previous page URL
                next:
                  type: string
                  nullable: true
                  description: Next page URL
                last:
                  type: string
                  description: Last page URL
                withHistory:
                  type: string
                  nullable: true
                  description: URL with version history included
                withoutHistory:
                  type: string
                  nullable: true
                  description: URL without version history
                withMetadata:
                  type: string
                  nullable: true
                  description: URL with manifest metadata included
                withoutMetadata:
                  type: string
                  nullable: true
                  description: URL without manifest metadata
    DpidQueryResult:
      type: object
      properties:
        dpid:
          type: integer
          description: DPID number
        owner:
          type: string
          description: Owner DID PKH address
        latestCid:
          type: string
          description: Latest manifest CID
        versionCount:
          type: integer
          description: Total number of versions
        source:
          type: string
          enum:
          - ceramic
          - legacy
          description: Data source type
        versions:
          type: array
          items:
            $ref: '#/components/schemas/DpidVersion'
          description: Version history (only included when history=true)
        metadata:
          $ref: '#/components/schemas/ManifestMetadata'
          description: Manifest metadata (only included when metadata=true)
        links:
          type: object
          properties:
            history:
              type: string
              description: URL to get full history
            latest:
              type: string
              description: URL to resolve latest version
            raw:
              type: string
              description: URL to get raw manifest
    DpidVersion:
      type: object
      properties:
        index:
          type: integer
          description: Zero-based version index
        cid:
          type: string
          description: IPFS CID for this version
        time:
          type: integer
          nullable: true
          description: Unix timestamp of version (null if pending)
        resolveUrl:
          type: string
          description: URL to resolve this specific version
    ResearchObject:
      type: object
      properties:
        id:
          type: string
          description: Stream ID
        owner:
          type: string
          description: Owner DID PKH
        manifest:
          type: string
          description: Manifest CID
        title:
          type: string
          description: Research object title
    ResearchObjectHistory:
      type: object
      properties:
        version:
          type: string
          description: Version identifier
        manifest:
          type: string
          description: Manifest CID for this version
        timestamp:
          type: string
          format: date-time
          description: Timestamp of version
    ResearchObjectQueryError:
      type: object
      properties:
        error:
          type: string
          description: Error message
        details:
          type: object
          description: Detailed error information
        params:
          type: object
          description: Request parameters
        path:
          type: string
          description: API path where error occurred
    ManifestMetadata:
      type: object
      properties:
        title:
          type: string
          description: Research object title
        description:
          type: string
          description: Research object description
        authors:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              orcid:
                type: string
          description: Array of authors
        keywords:
          type: array
          items:
            type: string
          description: Research keywords/tags
        license:
          type: string
          description: License information