How to Record a Data Processing Run in SSDS
This guide walks through registering a data processing event — a ProcessRun — in the Shore Side Data System (SSDS) so that the inputs, outputs, and software used are captured as metadata.
Example: The ProcessRun described below is an actual record that can be viewed in the Explorer at https://mooring-ssds.shore.mbari.org/explorer/ssds_metadata/dataproducer/?q=20260410T010521.
Overview
A ProcessRun is a Dataproducer record of type "ProcessRun". It links:
- the software that performed the processing
- the input Datacontainers consumed
- the output Datacontainer produced
- the person responsible for the run
- the resources associated with a ProcessRun
All of this is created in a single POST to /api/process-runs/.
Step 1 — Create an Account
Contact an SSDS administrator to create a user account for you, or sign up at
/accounts/signup/ if self-registration is enabled on your instance. Your
Your account must be a member of the ssds-editors group to have the necessary permissions to add ProcessRuns and related records.
Account Naming Conventions
SSDS uses email addresses as the login identifier. The address does not need to be a real, deliverable mailbox — it is used purely as a unique identifier. Two common patterns:
- Personal account — use your actual work email, e.g.
jsmith@mbari.org. - Service account — use an address that identifies the host and role,
e.g.
stoqsadm@kraken.shore.mbari.org, making it clear that requests come from an automated service running under thestoqsadmaccount onkraken.shore.mbari.org.
Note: this Django account email is used only for authentication. The
person_email field in the API payload is a completely separate lookup
into the SSDS Person metadata table — see Step 4.
Step 2 — Obtain an API Token
See docs/api-token-management.md for full instructions on generating, using, rotating, and revoking tokens.
In short, once your account exists an administrator can generate your token with:
# Production
docker compose run --rm django python manage.py drf_create_token <your-account-email>
Store the token securely. You will pass it in every request using the X-API-Key header.
Step 3 — Locate the API Docs
Interactive API documentation is available at /api/docs on your SSDS instance. The POST /api/process-runs/ endpoint is listed under process-runs. You can try requests directly from the browser after logging in.
Step 4 — Build Your Payload
Required Fields
| Field | Type | Description |
|---|---|---|
input_uris |
string[] |
URIs of the input Datacontainers consumed by this run |
software_name |
string |
Name of the processing software (e.g. "ds_to_netcdf") |
software_version |
string |
Version string (e.g. "1.2.3") or a git commit hash (e.g. "a3f1c9b") |
software_uristring |
string |
Canonical URI for the software — used as its unique key (e.g. a GitHub permalink) |
person_email |
email |
Email of the person responsible for the run — must match an existing Person record |
Commonly Used Optional Fields
| Field | Type | Description |
|---|---|---|
output_uri |
string |
URI of the Datacontainer produced by this run |
output_name |
string |
Human-readable name for the output (defaults to output_uri) |
producer_name |
string |
Name of the ProcessRun record itself (defaults to output_name) |
producer_description |
string |
Free-text description of what the run did |
startdate |
ISO 8601 datetime |
When processing started (e.g. "2026-03-15T08:00:00Z") |
enddate |
ISO 8601 datetime |
When processing finished |
output_startdate |
ISO 8601 datetime |
Temporal start of the data in the output file |
output_enddate |
ISO 8601 datetime |
Temporal end of the data in the output file |
output_minlatitude |
number |
Spatial bounds of the output (degrees) |
output_maxlatitude |
number |
|
output_minlongitude |
number |
|
output_maxlongitude |
number |
|
output_mindepth |
number |
Depth bounds of the output (metres, positive down) |
output_maxdepth |
number |
|
output_dodsurlstring |
string |
OPeNDAP URL for the output file |
input_dodsurlstrings |
string[] |
OPeNDAP URLs for each input (parallel to input_uris) |
resources |
object[] |
Any number of URL-referenceable resources to associate with this ProcessRun — log files, plots, provenance documents, or other ancillary items. Each object has the fields described below. |
Resource Object Fields
| Field | Required | Description |
|---|---|---|
uristring |
yes | URL of the resource (log file, plot image, web page, etc.) |
name |
no | Human-readable label (defaults to the URI if omitted) |
description |
no | Free-text description of what the resource contains |
mimetype |
no | MIME type, e.g. "text/plain", "image/png", "application/pdf" |
resourcetype_name |
no | Category label, e.g. "Log", "Plot", "Source Code", "Provenance" |
There is no limit on the number of resources per ProcessRun. Common uses include:
- Processing logs — the stdout/stderr captured during the run, served from a web-accessible path
- Diagnostic plots — PNG or PDF figures generated as QC output
- Provenance documents — links to notebooks, scripts, or configuration files that fully describe the processing
- Ancillary data — any other URL-referenceable file or page relevant to interpreting the output
Step 5 — POST to /api/process-runs/
curl Example
For a payload this large, save it to a file and reference it with @:
curl -X POST https://your-ssds-host/api/process-runs/ \
-H "X-API-Key: <your-token>" \
-H "Content-Type: application/json" \
-d @payload.json
Python Example
import requests
TOKEN = "<your-token>"
HOST = "https://your-ssds-host"
payload = {
"producer_name": (
"auv-python - Execution of process_lrauv.py to produce"
" ahi/missionlogs/2026/20260406_20260412/20260410T010521"
"/202604100105_202604100800_1S.nc"
),
"producer_description": (
"/Users/mccann/GitHub/auv-python/src/data/process_lrauv.py"
" -v 1 --auv_name ahi --start 20260409T000000 --end 20260415T000000"
" --update_ssds_provenance --clobber"
),
"input_uris": [
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521/202604100105_202604100800.nc4"
],
"input_dodsurlstrings": [
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521/202604100105_202604100800.nc4.html"
],
"software_name": "auv-python",
"software_version": "3ba7d45e5dcde5b9c13f07de481fe7703acad82b",
"software_uristring": (
"https://github.com/mbari-org/auv-python/tree"
"/3ba7d45e5dcde5b9c13f07de481fe7703acad82b"
),
"person_email": "mccann@mbari.org",
"startdate": "2026-04-16T19:28:23.073294+00:00",
"enddate": "2026-04-16T19:28:37.236252+00:00",
"output_startdate": "2026-04-10T01:05:21",
"output_enddate": "2026-04-10T08:00:12",
"output_minlatitude": 36.45515569382488,
"output_maxlatitude": 36.478055666399015,
"output_minlongitude": -122.60357983199621,
"output_maxlongitude": -122.52235802968319,
"output_mindepth": 0.04517268224547796,
"output_maxdepth": 211.1211725093574,
"output_uri": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521/202604100105_202604100800_1S.nc"
),
"output_dodsurlstring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521/202604100105_202604100800_1S.nc.html"
),
"resources": [
{
"name": "processing_script",
"uristring": (
"https://github.com/mbari-org/auv-python/blob"
"/3ba7d45e5dcde5b9c13f07de481fe7703acad82b"
"/src/data/process_lrauv.py"
),
"description": "Processing script: src/data/process_lrauv.py",
},
{
"name": "command_line",
"uristring": "urn:cmdline:MBARI2597.shore.mbari.org",
"description": (
"/Users/mccann/GitHub/auv-python/src/data/process_lrauv.py"
" -v 1 --auv_name ahi --start 20260409T000000"
" --end 20260415T000000 --update_ssds_provenance --clobber"
),
},
{
"name": "processing_log",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_processing.log"
),
"description": "Processing log file",
},
{
"name": "202604100105_202604100800_Group_BPC1.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_BPC1.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_Backseat.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_Backseat.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_BuoyancyServo.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_BuoyancyServo.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_CTD_Seabird.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_CTD_Seabird.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_CurrentEstimator.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_CurrentEstimator.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_DeadReckonUsingMultipleVelocitySources.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_DeadReckonUsingMultipleVelocitySources.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_ElevatorServo.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_ElevatorServo.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_MassServo.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_MassServo.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_NAL9602.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_NAL9602.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_Onboard.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_Onboard.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_PAR_Licor.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_PAR_Licor.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_RudderServo.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_RudderServo.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_Universals.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_Universals.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_WetLabsBB2FL.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_WetLabsBB2FL.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_Group_WetLabsUBAT.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_Group_WetLabsUBAT.nc"
),
"description": "Extracted by nc42netcdfs.py from 202604100105_202604100800.nc4",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_combined.nc4",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_combined.nc4"
),
"description": "Combined by combine.py",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_align.nc4",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_align.nc4"
),
"description": "Aligned by align.py",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_1S.nc",
"uristring": (
"http://dods.mbari.org/opendap/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_1S.nc"
),
"description": "Resampled by resample.py at 1S frequency",
"resourcetype_name": "NetCDF",
},
{
"name": "202604100105_202604100800_1S_2column_cmocean.png",
"uristring": (
"https://dods.mbari.org/data/lrauv/ahi/missionlogs/2026"
"/20260406_20260412/20260410T010521"
"/202604100105_202604100800_1S_2column_cmocean.png"
),
"description": "Created by create_products.py: Standard 2-column plot",
"resourcetype_name": "Quick Look Plot",
},
],
}
response = requests.post(
f"{HOST}/api/process-runs/",
json=payload,
headers={"X-API-Key": TOKEN},
)
response.raise_for_status()
print(f"Created ProcessRun with Dataproducer id={response.json()['id']}")
Successful Response
HTTP 201 Created
{"id": 4271}
The returned id is the Dataproducer record's primary key. You can view it in the Admin at /admin/ssds_metadata/dataproducer/<id>/change/.
Notes
- Idempotency: Re-posting with the same
software_uristringwill reuse the existing Software record rather than creating a duplicate. Input and output Datacontainers are similarly matched by URI. - Dates are UTC: All datetime fields are interpreted as UTC. Include the
Zsuffix or an explicit offset. - Depths are positive-down:
output_mindepth: 0.0,output_maxdepth: 150.0means the surface to 150 m depth.