Download OpenAPI specification:
Read-only, programmatic access to the publicly available water quality data hosted on DataStream - dataset metadata, monitoring locations, and observations.
Built on OData v4. Every endpoint returns the same JSON envelope and filters the same way.
This API is in Beta - changes will happen. We do our best to keep you informed of any breaking changes.
x-api-key header on every request.
Request one.429.$ as %24 in parameter names - send %24filter=..., not $filter=....
An unencoded $ is rejected at the edge before it reaches the API, and it is the single
most common cause of an unexpected 400.We have built modules to wrap around our API to make it easier to use. They handle
pagination, rate limiting and URL encoding for you, including the %24 rule above.
Many datasets are published under licences that require attribution. Retrieve Citation,
Licence and DOI from /Metadata before publishing or redistributing.
Retrieves the dataset-level metadata for the datasets that meet your query criteria.
| $select | Array of strings <= 23 items unique Items Enum: "Id" "DOI" "Version" "DatasetName" "DataStewardEmail" "DataCollectionOrganization" "DataUploadOrganization" "ProgressCode" "MaintenanceFrequencyCode" "Abstract" "DataCollectionInformation" "DataProcessing" "FundingSources" "DataSourceURL" "OtherDataSources" "Citation" "Licence" "Disclaimer" "TopicCategoryCode" "Keywords" "CreateTimestamp" "PublishedTimestamp" "TemporalExtent" Fields to return. Defaults to every allowed field. | ||||||||||||||||||||||||||||
| $filter | string OData filter expression, e.g. CharacteristicName eq 'pH' and ActivityStartYear ge '2020'.
| ||||||||||||||||||||||||||||
| $top | integer [ 1 .. 10000 ] Default: 10 | ||||||||||||||||||||||||||||
| $count | boolean Default: false Return only the count of matching rows (an estimate for large counts). | ||||||||||||||||||||||||||||
| $skiptoken | string Cursor for pagination, e.g. Id:1234. Use the Link header or @odata.nextLink from the previous response. |
curl -G -H 'x-api-key: PRIVATE-API-KEY' \ https://api.datastream.org/v1/odata/v4/Metadata \ --data-urlencode "\$select=DOI,DatasetName,Citation,Licence,Version" \ --data-urlencode "\$filter=DOI eq '10.25976/xxxx-xx00'" \ --data-urlencode "\$top=10000"
{- "odata.count": 1234,
- "value": [
- {
- "Id": "000000ab-000a-00a0-0aba-0ab00abc0a0a",
- "DOI": "10.25976/xxxx-xx00",
- "Version": "1.0.0",
- "DatasetName": "Sample Dataset A",
- "DataStewardEmail": "example@example.com",
- "DataCollectionOrganization": "Sample Organization A",
- "DataUploadOrganization": "Sample Organization B",
- "ProgressCode": "onGoing",
- "MaintenanceFrequencyCode": "asNeeded",
- "Abstract": "Sample Description",
- "DataCollectionInformation": "Sample Data Collection Information",
- "DataProcessing": "Sample Data Processing Information",
- "FundingSources": "Sample Funder A",
- "OtherDataSources": "",
- "Citation": "Sample Organization A. 2024. \"Sample Dataset A\" (dataset). 1.0.0. DataStream. https://doi.org/10.25976/xxxx-xx00.",
- "Disclaimer": "",
- "TopicCategoryCode": [
- "inlandWaters"
], - "Keywords": [
- "Water quality",
- "temperature"
], - "CreateTimestamp": "2020-01-01T15:30:00.000Z",
- "PublishedTimestamp": "2024-01-01T15:30:00.000Z",
- "TemporalExtent": [
- "2020-01-01",
- "2024-01-01"
]
}
]
}Retrieves the location information that meets your query criteria.
| $select | Array of strings <= 12 items unique Items Enum: "Id" "DOI" "ID" "Name" "Latitude" "Longitude" "HorizontalCoordinateReferenceSystem" "HorizontalAccuracyMeasure" "HorizontalAccuracyUnit" "VerticalMeasure" "VerticalUnit" "MonitoringLocationType" Fields to return. Defaults to every allowed field. | ||||||||||||||||||||||||||
| $filter | string OData filter expression, e.g. CharacteristicName eq 'pH' and ActivityStartYear ge '2020'.
| ||||||||||||||||||||||||||
| $top | integer [ 1 .. 10000 ] Default: 10 | ||||||||||||||||||||||||||
| $count | boolean Default: false Return only the count of matching rows (an estimate for large counts). | ||||||||||||||||||||||||||
| $skiptoken | string Cursor for pagination, e.g. Id:1234. Use the Link header or @odata.nextLink from the previous response. |
curl -G -H 'x-api-key: PRIVATE-API-KEY' \ https://api.datastream.org/v1/odata/v4/Locations \ --data-urlencode "\$select=Id,DOI,Name,Latitude,Longitude" \ --data-urlencode "\$filter=DOI eq '10.25976/xxxx-xx00'" \ --data-urlencode "\$top=10000"
{- "odata.count": 1234,
- "value": [
- {
- "Id": 99999,
- "DOI": "10.25976/xxxx-xx00",
- "ID": "ABC123",
- "Name": "Sample Location A",
- "Latitude": 51.01,
- "Longitude": -144.01,
- "HorizontalCoordinateReferenceSystem": "WGS84",
- "HorizontalAccuracyMeasure": 10,
- "HorizontalAccuracyUnit": "m",
- "VerticalMeasure": 76,
- "VerticalUnit": "m",
- "MonitoringLocationType": "River/Stream"
}
]
}Retrieves the observations that meet your query criteria.
| $select | Array of strings <= 34 items unique Items Enum: "Id" "DOI" "LocationId" "CharacteristicName" "ActivityType" "ActivityMediaName" "ActivityStartDate" "ActivityStartTime" "ActivityStartTimeZone" "ActivityEndDate" "ActivityEndTime" "ActivityEndTimeZone" "ActivityDepthHeightMeasure" "ActivityDepthHeightUnit" "SampleCollectionEquipmentName" "MethodSpeciation" "ResultSampleFraction" "ResultValue" "ResultUnit" "ResultValueType" "ResultDetectionCondition" "ResultDetectionQuantitationLimitUnit" "ResultDetectionQuantitationLimitMeasure" "ResultDetectionQuantitationLimitType" "ResultStatusID" "ResultComment" "ResultAnalyticalMethodID" "ResultAnalyticalMethodContext" "ResultAnalyticalMethodName" "AnalysisStartDate" "AnalysisStartTime" "AnalysisStartTimeZone" "LaboratoryName" "LaboratorySampleID" Fields to return. Defaults to every allowed field. | ||||||||||||||||||||
| $filter | string OData filter expression, e.g. CharacteristicName eq 'pH' and ActivityStartYear ge '2020'.
| ||||||||||||||||||||
| $top | integer [ 1 .. 10000 ] Default: 10 | ||||||||||||||||||||
| $count | boolean Default: false Return only the count of matching rows (an estimate for large counts). | ||||||||||||||||||||
| $skiptoken | string Cursor for pagination, e.g. Id:1234. Use the Link header or @odata.nextLink from the previous response. |
curl -G -H 'x-api-key: PRIVATE-API-KEY' \ https://api.datastream.org/v1/odata/v4/Observations \ --data-urlencode "\$select=DOI,ActivityStartDate,CharacteristicName,ResultValue,ResultUnit" \ --data-urlencode "\$filter=DOI eq '10.25976/xxxx-xx00' and CharacteristicName in ('Temperature, water', 'pH')" \ --data-urlencode "\$top=10000"
{- "odata.count": 1234,
- "value": [
- {
- "Id": 99999,
- "LocationId": 999,
- "DOI": "10.25976/xxxx-xx00",
- "ActivityType": "Field Msr/Obs-Portable Data Logger",
- "ActivityMediaName": "Surface Water",
- "ActivityStartDate": "2020-01-01",
- "ActivityStartTime": "15:30:00",
- "ActivityStartTimeZone": "-05:00",
- "ActivityEndDate": "2020-01-01",
- "ActivityEndTime": "16:30:00",
- "ActivityEndTimeZone": "-05:00",
- "ActivityDepthHeightMeasure": -0.25,
- "ActivityDepthHeightUnit": "m",
- "SampleCollectionEquipmentName": "Water Bottle",
- "CharacteristicName": "Dissolved oxygen saturation",
- "MethodSpeciation": "as N",
- "ResultSampleFraction": "Dissolved",
- "ResultValue": 97,
- "ResultUnit": "%",
- "ResultValueType": "Actual",
- "ResultDetectionCondition": "Below Detection/Quantification Limit",
- "ResultDetectionQuantitationLimitMeasure": 0.05,
- "ResultDetectionQuantitationLimitUnit": "mg/L",
- "ResultDetectionQuantitationLimitType": "Method Detection Level",
- "ResultStatusID": "Accepted",
- "ResultComment": "Sample comment",
- "ResultAnalyticalMethodID": "ABC123",
- "ResultAnalyticalMethodContext": "APHA",
- "ResultAnalyticalMethodName": "Sample Analytical Method A",
- "AnalysisStartDate": "2020-01-03",
- "AnalysisStartTime": "09:15:00",
- "AnalysisStartTimeZone": "-05:00",
- "LaboratoryName": "Sample Laboratory A",
- "LaboratorySampleID": "ABC123"
}
]
}Retrieves the data in the DataStream schema format with all columns that meet your query criteria.
| $select | Array of strings <= 44 items unique Items Enum: "Id" "DOI" "DatasetName" "MonitoringLocationID" "MonitoringLocationName" "MonitoringLocationLatitude" "MonitoringLocationLongitude" "MonitoringLocationHorizontalCoordinateReferenceSystem" "MonitoringLocationHorizontalAccuracyMeasure" "MonitoringLocationHorizontalAccuracyUnit" "MonitoringLocationVerticalMeasure" "MonitoringLocationVerticalUnit" "MonitoringLocationType" "ActivityType" "ActivityMediaName" "ActivityStartDate" "ActivityStartTime" "ActivityStartTimeZone" "ActivityEndDate" "ActivityEndTime" "ActivityEndTimeZone" "ActivityDepthHeightMeasure" "ActivityDepthHeightUnit" "SampleCollectionEquipmentName" "CharacteristicName" "MethodSpeciation" "ResultSampleFraction" "ResultValue" "ResultUnit" "ResultValueType" "ResultDetectionCondition" "ResultDetectionQuantitationLimitMeasure" "ResultDetectionQuantitationLimitUnit" "ResultDetectionQuantitationLimitType" "ResultStatusID" "ResultComment" "ResultAnalyticalMethodID" "ResultAnalyticalMethodContext" "ResultAnalyticalMethodName" "AnalysisStartDate" "AnalysisStartTime" "AnalysisStartTimeZone" "LaboratoryName" "LaboratorySampleID" Fields to return. Defaults to every allowed field. | ||||||||||||||||||||
| $filter | string OData filter expression, e.g. CharacteristicName eq 'pH' and ActivityStartYear ge '2020'.
| ||||||||||||||||||||
| $top | integer [ 1 .. 10000 ] Default: 10 | ||||||||||||||||||||
| $count | boolean Default: false Return only the count of matching rows (an estimate for large counts). | ||||||||||||||||||||
| $skiptoken | string Cursor for pagination, e.g. Id:1234. Use the Link header or @odata.nextLink from the previous response. |
curl -G -H 'x-api-key: PRIVATE-API-KEY' \ https://api.datastream.org/v1/odata/v4/Records \ --data-urlencode "\$select=DOI,ActivityStartDate,CharacteristicName,ResultValue,ResultUnit" \ --data-urlencode "\$filter=DOI eq '10.25976/xxxx-xx00' and ActivityStartYear ge '2020'" \ --data-urlencode "\$top=10000"
{- "odata.count": 1234,
- "value": [
- {
- "Id": 99999,
- "DOI": "10.25976/xxxx-xx00",
- "DatasetName": "Sample Dataset Name A",
- "MonitoringLocationID": "ABC123",
- "MonitoringLocationName": "Sample Location Name A",
- "MonitoringLocationLatitude": 51.01,
- "MonitoringLocationLongitude": -144.01,
- "MonitoringLocationHorizontalCoordinateReferenceSystem": "WGS84",
- "MonitoringLocationHorizontalAccuracyMeasure": 10,
- "MonitoringLocationHorizontalAccuracyUnit": "m",
- "MonitoringLocationVerticalMeasure": 76,
- "MonitoringLocationVerticalUnit": "m",
- "MonitoringLocationType": "River/Stream",
- "ActivityType": "Field Msr/Obs-Portable Data Logger",
- "ActivityMediaName": "Surface Water",
- "ActivityStartDate": "2010-01-01",
- "ActivityStartTime": "15:30:00",
- "ActivityStartTimeZone": "-05:00",
- "ActivityEndDate": "2020-01-01",
- "ActivityEndTime": "16:30:00",
- "ActivityEndTimeZone": "-05:00",
- "ActivityDepthHeightMeasure": -0.25,
- "ActivityDepthHeightUnit": "m",
- "SampleCollectionEquipmentName": "Water Bottle",
- "CharacteristicName": "Dissolved oxygen saturation",
- "MethodSpeciation": "as N",
- "ResultSampleFraction": "Dissolved",
- "ResultValue": 97,
- "ResultUnit": "%",
- "ResultValueType": "Actual",
- "ResultDetectionCondition": "Below Detection/Quantification Limit",
- "ResultDetectionQuantitationLimitMeasure": 0.05,
- "ResultDetectionQuantitationLimitUnit": "mg/L",
- "ResultDetectionQuantitationLimitType": "Method Detection Level",
- "ResultStatusID": "Accepted",
- "ResultComment": "Sample comment",
- "ResultAnalyticalMethodID": "ABC123",
- "ResultAnalyticalMethodContext": "APHA",
- "ResultAnalyticalMethodName": "Sample Analytical Method A",
- "AnalysisStartDate": "2020-01-03",
- "AnalysisStartTime": "09:15:00",
- "AnalysisStartTimeZone": "-05:00",
- "LaboratoryName": "Sample Laboratory A",
- "LaboratorySampleID": "ABC123"
}
]
}