Getting Started with DVIDS Content Submission API

This guide will walk you through getting up and running with the DVIDS Content Submission API.

1. Setting Up

Sign Up and Create an API App

  • Sign up for a DVIDS account.
  • Create a DVIDS API application.
  • Request upload capability by emailing: dvidsservicedesk@dvidshub.net.
  • Access the API reference documentation at: Submission API Docs.
  • The documentation is generated from OAS3, which can be viewed in Swagger UI or Postman and used to generate client libraries.

2. Authentication with DVIDS OAuth

Prerequisites

  • Ensure your redirect domain is listed in your DVIDS API App.

Authorization URL

The user authenticating must have submitter privileges in a DVIDS unit. Contact your unit PAO for help with this process.

Send the user to:

https://api.dvidshub.net/auth/authorize?client_id=<your-app-key>&redirect_uri=<your-redirect-url>&response_type=code&scope=basic%20email%20upload

Note: The upload scope is required for this application.

OAuth Flow

  • User logs in (if not already authenticated).
  • User is redirected to redirect_uri with a code querystring parameter.
  • Exchange code for an access_token and refresh_token via a POST request.

POST Request Details

Token Management

  • Use the refresh_token to obtain new tokens before expiry.
  • Important: Securely store and handle both tokens. Use encryption if possible.

Example

Below is an example of how to exchange the authorization code for an access token using Python's requests library:

import requests

def get_oauth_access_token(token_url, client_id, client_secret, code, redirect_uri):
    """
    Exchange an authorization code for an access token.
    """
    data = {
        'grant_type': 'authorization_code',
        'code': code,
        'redirect_uri': redirect_uri,
        'client_id': client_id,
        'client_secret': client_secret
    }

    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }

    response = requests.post(token_url, data=data, headers=headers)

    if response.status_code == 200:
        print(response.json())
    else:
        raise Exception(f"Failed to obtain access token: {response.status_code}, {response.text}")

get_oauth_access_token(
    'https://api.dvidshub.net/auth/access_token',
    '<your-api-key>',
    '<your-secret-key>',
    '<your-redirect-uri>',
    '<your-authorization-code>'
)

Uploading Content

  • Include the Authorization header with your access token prefixed by Bearer.
  • Set the Content-Type header to application/json.
  • Requests to create and modify resources require a type property in the request body.
  • Requests to modify resources via PATCH require an id property in the request body (as a string).

1. Creating a Batch

  • Use the POST /batch endpoint.
  • No additional attributes are required in the request body.
  • Store the returned id for subsequent requests.

2. Creating a News Story

  • Use the POST /batch/<batch_id>/news endpoint.
  • Use the batch_id from the previous step.
  • See the API documentation for required fields.

Selecting a Country

  • Use the GET /country endpoint to list available country codes.
  • Use the name querystring parameter to search by full or partial country name.
  • Use the iso2 code in the response to set the country field when creating a news story.
  • This same process applies for creating a Photo or Video.

3. Creating a BatchUpload

  • Use the POST /batch/<batch_id>/upload endpoint.
  • Only the type attribute is required in the request body.
  • The response includes an upload_url for uploading media files and an id to reference in future requests.

Uploading a Photo File

  • Use a PUT request.
  • Set the body to the binary content of the photo file.
  • Set the Content-Type header.
  • Do not use Transfer-Encoding: chunked — it is not supported and will return a 501 error.

4. Creating a Photo

  • Use the POST /batch/<batch_id>/photo endpoint.
  • Pass in the id from the upload step as the batch_upload relationship.

Creating Instructions

  • The instructions block is required and must include public release authority information.
  • Format: name, official email, and official phone number — each on a new line.
  • This information will be public, so avoid including any sensitive data.

Creating a VIRIN

  • The virin field is required for photos and videos and should be unique.
  • Use the endpoints below to generate a VIRIN.

Selecting a ServiceUnit

  • A ServiceUnit is required for photos and videos.
  • May also be required to generate a VIRIN.
  • Use the GET /service-unit endpoint to list available service units.

Selecting an Author

  • Not required but recommended.
  • Omitting an Author results in a "Courtesy Asset".
  • Use:

    • GET /author to list all authors
    • GET /service-unit/<service_unit_id>/author to filter by unit

Generating Author VIRIN

  • Use POST /author/<author_id>/virin
  • Must include the created_at date of the photo/video

Generating ServiceUnit VIRIN

  • Use POST /service-unit/<service_unit_id>/virin
  • Used if ServiceUnit is the main entity rather than an individual Author.

7. Creating a BatchMultipartUpload

  • Use POST /batch/<batch_id>/multipart-upload
  • Store the returned id for future requests.

Uploading the Video in Parts

  • Split the video into parts (5MB–5GB; 100MB recommended).
  • For each part, use POST /batch/<batch_id>/multipart-upload/<upload_id>/part
  • Use the returned upload_url to upload the part.
  • Capture the ETag from the PUT response — needed for finalization.

Closing the BatchMultipartUpload

  • Use PATCH /batch/<batch_id>/multipart-upload/<upload_id>
  • Finalizes the upload and is required before creating the video asset.

8. Creating a Video

  • Use POST /batch/<batch_id>/video
  • Pass the id from the multipart upload as the batch_upload relationship.

9. Associating Media with News Story

  • Use POST /batch/<batch_id>/news/<news_id>/media
  • Use the is_primary flag for the main asset if multiple are attached.

10. Closing the Batch

  • Use PATCH /batch/<batch_id>
  • Include the boolean closed: true in the request body.
  • This triggers media processing and approval workflows.

Check unit approval workflow status with GET /service-unit/<service_unit_id>. If approval is required, assets will not be publicly available until approved.

11. Checking Batch Status

  • GET /batch/<batch_id> — List all assets
  • GET /batch/<batch_id>/photo/<photo_id> — Check photo status
  • GET /batch/<batch_id>/video/<video_id> — Check video status

Advanced

1. Checking for Existing Photo Duplicates

Before uploading, check if the photo already exists:

  • Use ImageHash to hash the image
  • Use GET /photo with ahash, phash, dhash, and whash
  • Optionally include a virin
  • Tip: Use created_at or virin to confirm duplication

2. Disabling the Batch Close Email

To suppress batch close emails (useful for bulk processing):

  • See PATCH /batch/<batch_id> endpoint in the API documentation