{"id":19227473,"url":"https://github.com/datastreamapp/api-docs","last_synced_at":"2025-02-23T10:26:00.259Z","repository":{"id":47650605,"uuid":"308393711","full_name":"datastreamapp/api-docs","owner":"datastreamapp","description":"DataStream Public API Documentation","archived":false,"fork":false,"pushed_at":"2024-10-31T15:18:24.000Z","size":208,"stargazers_count":9,"open_issues_count":1,"forks_count":1,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-01-04T22:20:19.074Z","etag":null,"topics":["api","odata","rest","wqx"],"latest_commit_sha":null,"homepage":"https://datasteam.org","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/datastreamapp.png","metadata":{"files":{"readme":"docs/README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-29T16:55:13.000Z","updated_at":"2024-11-08T19:46:38.000Z","dependencies_parsed_at":"2022-09-15T09:41:53.782Z","dependency_job_id":"64d7b9cc-e39a-42a6-b88d-44e95463cdab","html_url":"https://github.com/datastreamapp/api-docs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datastreamapp%2Fapi-docs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datastreamapp%2Fapi-docs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datastreamapp%2Fapi-docs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datastreamapp%2Fapi-docs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/datastreamapp","download_url":"https://codeload.github.com/datastreamapp/api-docs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240301473,"owners_count":19779825,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","odata","rest","wqx"],"created_at":"2024-11-09T15:23:31.365Z","updated_at":"2025-02-23T10:26:00.190Z","avatar_url":"https://github.com/datastreamapp.png","language":null,"funding_links":[],"categories":["Index"],"sub_categories":["Open Data"],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/gordonfn/api/main/docs/images/datastream.svg?sanitize=true\" alt=\"DataStream Logo\" width=\"400\"\u003e\n  \u003cbr/\u003e\n  DataStream Public API\n  \u003cbr/\u003e\n  \u003cbr/\u003e\n\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://docs.google.com/forms/d/1SjPVeblz2QFaghpiBZPZKOVNKXgw5UMnAtJLJS1tQYI\"\u003eRequest an API Key\u003c/a\u003e\n\u003c/p\u003e\n\nOur public API uses the ISO/IEC 20802-2 Standard known as [OData JSON Format v4](https://odata.org).\n\n## Attribution/Citation\nThank you ahead of time for using this data responsibly and providing the appropriate citations when necessary when being presented to external parties. These citations must be accompanied by a link to the DOI (https://doi.org/{value}). The licence, citation, and DOI can be retrieved from the `/Metadata` endpoint.\n\n## Modules\nWe have built modules to wrap around our API to make it easier to use.\n- [`R`](https://github.com/datastreamapp/datastreamr)\n- [`Python`](https://github.com/datastreamapp/datastream-py)\n- [`JavaScript`](https://github.com/datastreamapp/datastreamjs)\n- [`Shell`](https://github.com/datastreamapp/datastreamsh)\n\nFor those building their own implementation, here are some key things to keep in mind:\n- Querystring parameters must be URL encoded. All languages should have a function to do this.\n- Requests to Observations/Records that you expect a large amount (\u003e1M rows) of data from should be partitioned. We recommend by Monitoring locations and/or activity start year. There is a technical database reason for this that you're welcome to ask us about.\n- Each request partition should be paginated over using the `Link` header or `@odata.nextLink` within the body of the response.\n- Rate limit yourself (2 reqs/sec) and don't make requests in parallel. This will ensure you don't get `429 Too Many Requests` error response.\n- Use HTTP/3\n\n## Endpoints\nYou can test out your script by prefixing `https://api.qa.datastream.org/v1/odata/v4` to the endpoints.\nWhen you're ready to pull data from the production system you can use: `https://api.datastream.org/v1/odata/v4`.\nFor browser requests all you need to do is let us know your domain name and we can add it to the CORS whitelist, only GET requests are supported. All other application should store the API Key in the header `x-api-key`.\n\nRemember that your API key is for your use only. Please do not share your API key. If it does become public, please let us know, we can give you a new one.\n\n- **GET /Metadata**\n  - Retrieves the dataset-level metadata for the datasets that meet your query criteria.   \n  - Select By: `DOI`, `Version`, `DatasetName`, `DataStewardEmail`, `DataCollectionOrganization`, `DataUploadOrganization`, `ProgressCode`, `MaintenanceFrequencyCode`, `Abstract`, `DataCollectionInformation`, `DataProcessing`, `FundingSources`, `DataSourceURL`, `OtherDataSources`, `Citation`,   `Licence`, `Disclaimer`, `TopicCategoryCode`, `Keywords`, `CreateTimestamp`, `PublishedTimestamp`\n  - Filter By: `DOI`, `LocationId`, `ActivityMediaName`, `ActivityGroupType`, `CharacteristicName`, `MonitoringLocationType`, `ActivityStartYear`, `RegionId`, `LatitudeNormalized`\\*, `LongitudeNormalized`\\*, `DatasetName`, `CreateTimestamp`\n\n- **GET /Locations**\n  - Retrieves the location information that meets your query criteria.\n  - Select By: `Id`, `DOI`, `ID` (Maps to `MonitoringLocationID` internally), `Name`, `Latitude`, `Longitude`, `HorizontalCoordinateReferenceSystem`, `HorizontalAccuracyMeasure`, `HorizontalAccuracyUnit`, `VerticalMeasure`, `VerticalUnit`, `MonitoringLocationType`, `LatitudeNormalized`\\*, `LongitudeNormalized`\\*, `HorizontalCoordinateReferenceSystemNormalized`\\*\n  - Filter By: `DOI`, `LocationId`, `ActivityMediaName`, `ActivityGroupType`, `CharacteristicName`, `MonitoringLocationType`, `ActivityStartYear`, `RegionId`, `LatitudeNormalized`\\*, `LongitudeNormalized`\\*, `Name`\n\n- **GET /Observations**\n  - Retrieves the observations that meet your query criteria. \n  - Select By: `Id`,`LocationId`,  `DOI`, `ActivityType`, `ActivityMediaName`, `ActivityStartDate`, `ActivityStartTime`, `ActivityStartTimeZone`, `ActivityEndDate`, `ActivityEndTime`, `ActivityEndTimeZone`, `ActivityDepthHeightMeasure`, `ActivityDepthHeightUnit`, `SampleCollectionEquipmentName`, `CharacteristicName`, `MethodSpeciation`, `ResultSampleFraction`, `ResultValue`, `ResultUnit`, `ResultValueType`, `ResultDetectionCondition`, `ResultDetectionQuantitationLimitUnit`, `ResultDetectionQuantitationLimitMeasure`, `ResultDetectionQuantitationLimitType`, `ResultStatusID`, `ResultComment`, `ResultAnalyticalMethodID`, `ResultAnalyticalMethodContext`, `ResultAnalyticalMethodName`, `AnalysisStartDate`, `AnalysisStartTime`, `AnalysisStartTimeZone`, `LaboratoryName`, `LaboratorySampleID`\n  - Filter By: `DOI`, `LocationId`, `ActivityMediaName`, `ActivityGroupType`, `CharacteristicName`, `MonitoringLocationType`, `ActivityStartYear`, `RegionId`, `LatitudeNormalized`\\*, `LongitudeNormalized`\\*\n\n \\* Normalized coordinates are in `WGS84` projection.\n \n- **GET /Records**\n  - Retrieves the data in the DataStream schema format with all columns that meet your query criteria.\n  - Only intended for streaming data directly into a CSV file. For all other use cases, we recommend using `/Observations` endpoint.\n  - Select By: `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`\n  - Filter By: `DOI`, `LocationId`, `ActivityMediaName`, `ActivityGroupType`, `CharacteristicName`, `MonitoringLocationType`, `ActivityStartYear`, `RegionId`\n\n\n \n### Body Object\n```json\n{\n  \"@data.context\": \"odata/v4/Records/$links/Metadata(Id=@DatasetId)\"\n  \"value\":[\n      ...\n  ]\n}\n```\n\n### URL Parameters\nOData accepts certain query parameters. The ones supported by this API are:\n- **$select**\n  - Fields to be selected are entered comma delimited.\n  - Example: `$select=DatasetName,Abstract`\n  - Default: All columns available.\n- **$filter**\n  - Available operators: `in`, `eq`, `lt`, `gt`, `lte`, `gte`, `ne`\n  - Grouping: `$filter=CharacteristicName eq 'Dissolved oxygen saturation'` or `$filter=DOI eq '10.25976/{suffix}'` where `{suffix}` is replaced with a value.\n  - Temporal: `$filter=CreateTimestamp gt '2020-03-23' and CreateTimestamp lt '2020-03-25'`\n  - Spatial: `$filter=RegionId eq 'hub.atlantic'`\n    - RegionId Values (these values are subject to change):\n      - Partner Hubs: `hub.{atlantic,greatlakes,lakewinnipeg,mackenzie,pacific}`\n      - Countries: `admin.2.{ca}`\n      - Provinces/Territories/States: `admin.4.ca.{ab,bc,mb,nb,nl,ns,nt,nu.on,pe,,qc,sk,yt}`\n    - Bounding box `$filter=LongitudeNormalized gt '-102.01' and LongitudeNormalized lt '-88.99' and LatitudeNormalized gt '49' and LatitudeNormalized lt '60'`\n  \u003c!-- - Functions: `$filter=contains(DOI, 'xxxx')`, `$filter=startwith(DOI, 'xxxx')`, `$filter=endswith(DOI, 'xxxx-xxxx')` --\u003e\n- **$top**\n  - Maximum: 10000\n  - Example: `$top=10`\n- **$skiptoken**\n  - Return the next items after the skipped token\n  - Example: `$skiptoken=Id:1234`\n  - For pagination, use `Link` header or `@odata.nextLink` in the JSON response body\n- **$count**\n  - Return only the count for the request. When the value is large enough it becomes an estimate (~0.0005% accurate)\n  - Example: `$count=true`\n  - Default: `false`\n\u003c!--\n- **$orderby**\n  - Fields to order by are entered comma delimited.\n  - Example: `$orderby=DatasetName,CreateTimestamp`\n- **$skip**\n  - Example: `$skip=10`\n--\u003e\n\nWhen building an integration with any API, it's important to encode all query string parameters.\n\n### Performance Tips\n- Using `$select` to request only the parameters you need will decrease the amount of data needed to be transfer.\n\u003c!--\n- Using large `$skip` values can be slow (it's a database thing), slicing your data by `GeometryId` and/or `CharacteristicName` will help prevent this.\n- Don't use `$orderby` unless you plan to pull a smaller number of results.\n--\u003e\n\n## Examples\n\n### Metadata\n\n#### Get all datasets in `Mackenzie` and `Lake Winnipeg` DataStream hubs\n```bash\ncurl -G -H 'x-api-key: PRIVATE-API-KEY' \\\n     https://api.datastream.org/v1/odata/v4/Metadata \\\n     --data-urlencode \"\\$select=DOI,DatasetName,Licence,Citation,Version\" \\\n     --data-urlencode \"\\$filter=RegionId in ('hub.mackenzie', 'hub.lakewinnipeg')\"\n```\n\n#### Get the citation and licence for a dataset:\n```bash\ncurl -G -H 'x-api-key: PRIVATE-API-KEY' \\\n     https://api.datastream.org/v1/odata/v4/Metadata \\\n     --data-urlencode \"\\$select=DOI,DatasetName,Licence,Citation,Version\" \\\n     --data-urlencode \"\\$filter=endswith(DOI, 'xxxx-xxxx')\" \\\n```\n\n### Locations\n\n#### Get Locations from a dataset\n```bash\ncurl -G -H 'x-api-key: PRIVATE-API-KEY' \\\n     https://api.datastream.org/v1/odata/v4/Locations \\\n     --data-urlencode \"\\$filter=DOI eq '10.25976/xxxx-xx00'\"\n```\n\n#### Get Locations from multiple datasets\n```bash\ncurl -G -H 'x-api-key: PRIVATE-API-KEY' \\\n     https://api.datastream.org/v1/odata/v4/Locations \\\n     --data-urlencode \"\\$filter=DOI in ('10.25976/xxxx-xx00', '10.25976/xxxx-xx00', '10.25976/xxxx-xx00')\"\n```\n\n### Observations\n\n#### Get Temperature and pH observations from multiple datasets\n```bash\ncurl -G -H 'x-api-key: PRIVATE-API-KEY' \\\n     https://api.datastream.org/v1/odata/v4/Observations \\\n     --data-urlencode \"\\$filter=DOI in ('10.25976/xxxx-xx00', '10.25976/xxxx-xx00', '10.25976/xxxx-xx00') and CharacteristicName in ('Temperature, water', 'pH')\"\n```\n\n#### Get all `pH` observations in `Alberta`:\n```bash\ncurl -G -H 'x-api-key: PRIVATE-API-KEY' \\\n     https://api.datastream.org/v1/odata/v4/Observations \\\n     --data-urlencode \"\\$filter=CharacteristicName eq 'pH' and RegionId eq 'admin.4.ca.ab'\"\n```\n\n## Response Format\n```json\n{\n  \"value\": [{\n    \"Id\": \"UUID\",\n    ...\n  }],\n  \"@odata.nextLink\": \"https://api.datastream.org/v1/odata/v4/Observations?$skiptoken=Id:99999\u0026$top=1000\"\n}\n```\n\n## Errors\n### 408 or 504 Timeout\nThis means your request was too complicated and was unable to complete within 30sec. Lowering `$top` and/or adding in narrower filtering should resolve this issue.\n\n### 413 Payload Too Large\nThis means your request result was too large. Lowering `$top` or only requesting the values you need should resolve this issue.\n\n### 429 Too Many Requests\nThis status code indicates that the client has sent too many requests in a given amount of time. To resolve this issue, rate limit yourself (2 reqs/sec) and don't make requests in parallel.\n\n## Disclaimer\nWe are currently in a Beta, changes will happen. We will do our best effort to keep you informed of any breaking changes.\n\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"http://gordonfoundation.ca\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/gordonfn/api/main/docs/images/the-gordon-foundation.svg?sanitize=true\" alt=\"The Gordon Foundation Logo\" width=\"200\"\u003e\u003c/a\u003e\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatastreamapp%2Fapi-docs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatastreamapp%2Fapi-docs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatastreamapp%2Fapi-docs/lists"}