API Reference

Complete REST API documentation for DOCiD™ publication and document identifier management

API Design Principles

The DOCiD™ API is built following RESTful principles with comprehensive support for metadata management, persistent identifiers, and scholarly communication workflows.

RESTful Architecture

  • Resource-oriented URLs following REST conventions
  • HTTP verb semantics (GET, POST, PUT, DELETE)
  • Standard HTTP status code usage
  • JSON-based request/response payloads
  • Consistent API versioning via URL prefix

Authentication & Authorization

  • JWT-based authentication with access/refresh tokens
  • Bearer token authorization headers
  • Social OAuth integration (Google, ORCID, GitHub)
  • Role-based access control (user, admin, superadmin)
  • Resource-level permission management

Error Handling

  • Consistent error response format across all endpoints
  • HTTP status code compliance with detailed error codes
  • Comprehensive validation error messages
  • Request parameter validation and sanitization
  • Graceful handling of external service failures

Standard Response Format

All API responses follow a consistent structure for both success and error cases, facilitating predictable client-side handling.

Success Response Structure
HTTP 200-299
Standard Success Response
{
    "status": "success",
    "data": {
        // Response payload with requested data
        "publication": {
            "id": 1,
            "document_title": "Research Publication Title",
            "doi": "10.5555/docid.example.001"
        }
    },
    "message": "Operation completed successfully",
    "timestamp": "2024-01-15T10:30:00Z"
}
Error Response Structure
HTTP 400-599
Standard Error Response
{
    "status": "error",
    "error": "Validation failed for publication data",
    "code": "VALIDATION_ERROR",
    "details": {
        "field_errors": {
            "document_title": "Title is required and cannot be empty",
            "creators": "At least one creator must be specified"
        },
        "request_id": "req_abc123def456"
    },
    "timestamp": "2024-01-15T10:30:00Z"
}

Authentication Endpoints

Authentication system supporting both traditional email/password and social OAuth providers (Google, ORCID, GitHub) with JWT-based session management.

POST /api/v1/auth/login
Authentication User Login

Authenticate user credentials and receive JWT access and refresh tokens for subsequent API requests.

Request Parameters:

Field Type Required Description
email string Yes User's registered email address
password string Yes User's password (minimum 8 characters)
Request Example
POST /api/v1/auth/login
Content-Type: application/json

{
    "email": "amara.okonkwo@uct.ac.za",
    "password": "SecurePass123!"
}
Success Response (HTTP 200)
{
    "status": "success",
    "data": {
        "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
        "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
        "expires_in": 3600,
        "user": {
            "user_id": 1,
            "full_name": "Dr. Amara Okonkwo",
            "email": "amara.okonkwo@uct.ac.za",
            "role": "user",
            "orcid_id": "0000-0002-1234-5678",
            "affiliation": "University of Cape Town",
            "ror_id": "https://ror.org/01ggx4157"
        }
    },
    "message": "Authentication successful"
}
POST /api/v1/auth/store-registration-token

User Registration

Register new user account

Request Body

{
    "email": "user@example.com",
    "full_name": "John Doe",
    "password": "secure_password",
    "orcid_id": "0000-0000-0000-0000",
    "affiliation": "University Name"
}
POST /api/v1/auth/request-password-reset

Password Reset Request

Request password reset email

Request Body

{
    "email": "user@example.com"
}

Publication Management Endpoints

Comprehensive publication lifecycle management including creation, metadata management, identifier assignment, and external service integration based on the Publications model.

POST /api/v1/publications/publish

Create Publication

Create new publication with metadata

Authorization: Bearer {jwt_token}

Request Body

{
    "title": "Research Paper Title",
    "abstract": "Paper abstract...",
    "resource_type_id": 1,
    "publication_type_id": 1,
    "creators": [
        {
            "creator_name": "John Doe",
            "orcid_id": "0000-0000-0000-0000",
            "role_id": 1,
            "affiliation": "University Name"
        }
    ],
    "organizations": [
        {
            "organization_name": "University Name",
            "ror_id": "ror_id_here",
            "country": "Country Name"
        }
    ],
    "funders": [
        {
            "funder_name": "Grant Agency",
            "grant_number": "GRANT-2023-001",
            "award_amount": 50000.00
        }
    ]
}
GET /api/v1/publications/get-publications

Get Publications List

Retrieve paginated list of publications

Authorization: Bearer {jwt_token}

Query Parameters: page, limit, resource_type

Response

{
    "publications": [
        {
            "id": 1,
            "title": "Research Paper Title",
            "docid": "DOCID.001",
            "doi": "10.5555/example.doi",
            "resource_type": "dataset",
            "creators": [...],
            "organizations": [...],
            "created_at": "2023-01-01T00:00:00Z"
        }
    ],
    "pagination": {
        "page": 1,
        "pages": 5,
        "total": 50,
        "limit": 10
    }
}
GET /api/v1/publications/get-publication/{id}

Get Single Publication

Retrieve detailed publication information

Authorization: Bearer {jwt_token}

GET /api/v1/publications/docid/{docid}

Get Publication by DOCiD™

Retrieve publication using DOCiD™ identifier

Comments System Endpoints

Hierarchical commenting system supporting threaded discussions, moderation, and engagement tracking based on the PublicationComments model with parent-child relationships.

GET /api/publications/{publication_id}/comments

Get Publication Comments

Retrieve hierarchical comments for a publication

Query Parameters: include_replies=true

Response

{
    "publication_id": 1,
    "total_comments": 5,
    "comments": [
        {
            "id": 1,
            "user_id": 1,
            "user_name": "John Doe",
            "comment_text": "Great research work!",
            "comment_type": "general",
            "status": "active",
            "likes_count": 3,
            "created_at": "2023-01-01T10:00:00Z",
            "replies": [
                {
                    "id": 2,
                    "user_id": 2,
                    "user_name": "Jane Smith",
                    "comment_text": "I agree, very insightful.",
                    "parent_comment_id": 1,
                    "created_at": "2023-01-01T11:00:00Z"
                }
            ]
        }
    ]
}
POST /api/publications/{publication_id}/comments

Add Comment

Add new comment to publication

Authorization: Bearer {jwt_token}

Request Body

{
    "user_id": 1,
    "comment_text": "This is a great contribution to the field.",
    "comment_type": "review"
}
POST /api/publications/{publication_id}/comments

Add Reply

Add reply to existing comment

Authorization: Bearer {jwt_token}

Request Body

{
    "user_id": 1,
    "comment_text": "Thank you for the feedback!",
    "comment_type": "general",
    "parent_comment_id": 1
}
PUT /api/comments/{comment_id}

Edit Comment

Edit existing comment (author only)

Authorization: Bearer {jwt_token}

Request Body

{
    "user_id": 1,
    "comment_text": "Updated comment text"
}
DELETE /api/comments/{comment_id}

Delete Comment

Soft delete comment (author or admin)

Authorization: Bearer {jwt_token}

Request Body

{
    "user_id": 1
}
POST /api/comments/{comment_id}/like

Like Comment

Toggle like status for comment

Authorization: Bearer {jwt_token}

GET /api/comments/stats/{publication_id}

Get Comment Statistics

Retrieve comment analytics for publication

Response

{
    "publication_id": 1,
    "statistics": {
        "total_comments": 10,
        "top_level_comments": 7,
        "replies": 3,
        "unique_commenters": 5,
        "total_likes": 15,
        "comment_types": {
            "general": 6,
            "review": 3,
            "question": 1
        }
    }
}

External Service Integration Endpoints

Integration endpoints for scholarly communication infrastructure including Crossref, ROR, ORCID, CORDRA, and CSTR services for metadata enrichment and identifier resolution.

GET /api/v1/crossref/doi/{doi}

Get DOI Metadata from Crossref

Retrieve metadata for specific DOI

Authorization: Bearer {jwt_token}

POST /api/v1/crossref/search

Search Crossref Database

Search publications in Crossref

Authorization: Bearer {jwt_token}

Request Body

{
    "query": "machine learning",
    "rows": 10,
    "sort": "relevance"
}
GET /api/v1/ror/search

Search ROR Organizations

Search research organizations

Authorization: Bearer {jwt_token}

Query Parameters: query

GET /api/v1/orcid/{orcid_id}

Get ORCID Information

Retrieve researcher profile from ORCID

Authorization: Bearer {jwt_token}

POST /api/v1/cordoi/assign-identifier/apa-handle

Assign Handle Identifier

Assign Handle identifier via CORDRA

Authorization: Bearer {jwt_token}

Reference Data Endpoints

GET /api/v1/publications/get-resource-types

Get Resource Types

Retrieve available resource type classifications

GET /api/v1/publications/get-creators-roles

Get Creator Roles

Retrieve available creator role taxonomies

GET /api/v1/publications/get-publication-types

Get Publication Types

Retrieve document type classifications

File Upload Endpoints

POST /uploads

Upload Publication Files

Upload files associated with publications

Authorization: Bearer {jwt_token}

Content-Type: multipart/form-data

Form Data

file: [binary file data]
publication_id: 1
file_type: document

Rate Limiting

The API implements rate limiting on sensitive endpoints:

Endpoint Category Rate Limit Time Window
Authentication endpoints 5 requests per minute
Publication creation 10 requests per hour
External service calls 100 requests per hour
Comment creation 30 requests per hour

Rate Limit Headers

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200

HTTP Status Codes & Error Codes

HTTP Status Codes

  • 200 OK - Successful request
  • 201 Created - Resource created successfully
  • 400 Bad Request - Invalid request data
  • 401 Unauthorized - Authentication required
  • 403 Forbidden - Insufficient permissions
  • 404 Not Found - Resource not found
  • 409 Conflict - Resource conflict
  • 422 Unprocessable Entity - Validation error
  • 429 Too Many Requests - Rate limit exceeded
  • 500 Internal Server Error - Server error

Application Error Codes

  • INVALID_CREDENTIALS - Login credentials incorrect
  • USER_NOT_FOUND - User account does not exist
  • PUBLICATION_NOT_FOUND - Publication does not exist
  • COMMENT_NOT_FOUND - Comment does not exist
  • UNAUTHORIZED_ACCESS - Insufficient permissions
  • VALIDATION_ERROR - Input validation failed
  • EXTERNAL_SERVICE_ERROR - External API error
  • DATABASE_ERROR - Database operation failed

Verification & Integrity Endpoints

Public, unauthenticated. Full detail in Integrity & Checksums.

Method & path Auth Purpose
GET /api/v1/verify?identifier=<docid> None Stored SHA-256 fingerprints for every object in a DOCiD. Prefer this form — DOCiDs contain slashes
GET /api/v1/verify/<docid> None Path form of the same lookup

Returns 400 without an identifier, 404 when no such DOCiD exists, and 410 when the record has been retired.

Subsystem Endpoints

Endpoint groups added since v1.0 of this documentation. Only the integration surface is listed; administrative routes are deliberately omitted.

Local Contexts

Method & path Auth Purpose
GET /api/v1/localcontexts/projects None List Local Contexts Hub projects
GET /api/v1/localcontexts/projects/search None Search Hub projects
GET /api/v1/localcontexts/publications/<id>/contexts None TK/BC labels and Notices attached to a publication
POST /api/v1/localcontexts/publications/<id>/projects JWT Attach every label of a Hub project in one transaction
GET /api/v1/localcontexts/publications/<id>/projects-display None Display-ready project view; falls back to the local cache when the Hub is unreachable

Local Contexts data is not part of publication metadata responses

Labels and Notices are not included in get-publication or the resolvers. A client that needs them must make a second call to one of the endpoints above.

Research resources (RRID)

Method & path Auth Purpose
GET /api/v1/rrid/search JWT Search SciCrunch for a research resource
GET /api/v1/rrid/resolve JWT Resolve a single RRID to its metadata
POST /api/v1/rrid/attach JWT Attach an RRID to a publication, organization, or document
GET /api/v1/rrid/entity None RRIDs attached to a given entity
DELETE /api/v1/rrid/<id> JWT Detach an RRID

Resolved RRID metadata appears in publication responses as research_resources[], and is also merged inline into each attached document and organization entry.

Versioning

Method & path Auth Purpose
GET /api/v1/publications/versions/<id> None The full version chain — walks up to the root and returns every sibling version
POST /api/v1/publications/version JWT, owner only Create a new version of a record. Returns 403 for a non-owner

Versions form a flat chain, not a tree: versioning a version reparents to the root. Each version is an independent record with its own DOCiD, its own files, and its own checksums.

Tenant branding

Method & path Auth Purpose
GET /api/v1/tenants/<slug> None Whitelabel branding for a tenant — logos, colours, page copy

Tenancy is branding, not data scoping

All tenants share the same underlying records. A tenant slug changes presentation only; it does not partition or filter data. The mechanism that does restrict what an account may do is account-category filtering, described in the authorization matrix.