{"openapi":"3.1.0","info":{"title":"Fire Aware Developer API","version":"1.0.0","summary":"Project-scoped ingestion and retrieval for air-quality and wildfire sensor data.","description":"The Fire Aware Developer API lets a project register sources, publish observations into private or public datasets, and read data according to key scopes. Human project management uses a Supabase session; machine ingestion and retrieval use project API keys.","contact":{"name":"Fire Aware Developer Support","email":"support@fire-aware.app","url":"https://www.fire-aware.app/developer"},"license":{"name":"See Fire Aware terms","url":"https://www.fire-aware.app/terms"}},"servers":[{"url":"https://www.fire-aware.app","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"tags":[{"name":"Auth","description":"Developer portal and account session helpers."},{"name":"Account","description":"The signed-in developer account and profile."},{"name":"Catalog","description":"Public dataset discovery."},{"name":"Projects","description":"Developer projects and API keys."},{"name":"Sources","description":"Telemetry sources owned by a project."},{"name":"Datasets","description":"Observation containers and sharing."},{"name":"Ingest","description":"Authenticated observation writes."},{"name":"Data","description":"Authenticated observation reads."},{"name":"Usage","description":"Project request accounting."}],"paths":{"/v1/openapi.json":{"get":{"tags":["Catalog"],"summary":"This OpenAPI document","operationId":"getOpenApi","responses":{"200":{"description":"OpenAPI 3.1 document","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/measurements":{"get":{"tags":["Catalog"],"summary":"List active measurement definitions","operationId":"listMeasurements","responses":{"200":{"description":"Supported measurement codes, units and ranges","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeasurementsResponse"}}}},"500":{"$ref":"#/components/responses/Error"}}}},"/v1/auth/login":{"post":{"tags":["Auth"],"summary":"Sign in to the developer portal","operationId":"login","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Credentials"}}}},"responses":{"200":{"description":"Developer session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/auth/signup":{"post":{"tags":["Auth"],"summary":"Create a developer account","operationId":"signup","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupCredentials"}}}},"responses":{"201":{"description":"Session or email-confirmation requirement","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/auth/refresh":{"post":{"tags":["Auth"],"summary":"Refresh a developer session","operationId":"refreshSession","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["refresh_token"],"properties":{"refresh_token":{"type":"string"}}}}}},"responses":{"200":{"description":"Refreshed session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/auth/logout":{"post":{"tags":["Auth"],"summary":"Sign out a developer session","operationId":"logout","security":[{"developerSession":[]}],"responses":{"200":{"description":"Signed out"}}}},"/v1/auth/providers":{"get":{"tags":["Auth"],"summary":"List enabled social sign-in providers","operationId":"listAuthProviders","responses":{"200":{"description":"Providers currently enabled by Supabase","content":{"application/json":{"schema":{"type":"object","properties":{"providers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["google","github","apple"]},"label":{"type":"string"}}}},"unavailable":{"type":"boolean"}}}}}}}}},"/v1/auth/oauth/{provider}/start":{"get":{"tags":["Auth"],"summary":"Start a social sign-in redirect","operationId":"startOAuth","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","enum":["google","github","apple"]}},{"name":"return_to","in":"query","schema":{"type":"string","enum":["/account","/developer"]}}],"responses":{"302":{"description":"Redirect to the provider's authorization page"},"400":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/v1/auth/oauth/callback":{"get":{"tags":["Auth"],"summary":"Complete a social sign-in callback","operationId":"completeOAuthCallback","parameters":[{"name":"code","in":"query","required":false,"schema":{"type":"string"}},{"name":"state","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"302":{"description":"Redirect back to the account or developer return path"},"503":{"$ref":"#/components/responses/Error"}}}},"/v1/auth/oauth/handoff":{"post":{"tags":["Auth"],"summary":"Exchange the encrypted OAuth handoff cookie for a session","operationId":"exchangeOAuthHandoff","responses":{"200":{"description":"Session for tab-scoped browser storage","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"400":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/account/profile":{"get":{"tags":["Account"],"summary":"Read the signed-in account and developer profile","operationId":"getAccountProfile","security":[{"developerSession":[]}],"responses":{"200":{"description":"Account identity and profile","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Account"],"summary":"Update the signed-in developer profile","operationId":"updateAccountProfile","security":[{"developerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"display_name":{"type":["string","null"],"maxLength":120},"organization":{"type":["string","null"],"maxLength":120}}}}}},"responses":{"200":{"description":"Updated profile","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}}}},"/v1/catalog/datasets":{"get":{"tags":["Catalog"],"summary":"List public datasets","operationId":"listPublicDatasets","parameters":[{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"Public dataset metadata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetsResponse"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/catalog/observations":{"get":{"tags":["Catalog"],"summary":"Read recent observations from public datasets","operationId":"listPublicObservations","parameters":[{"$ref":"#/components/parameters/Limit"},{"name":"dataset_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"start","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"end","in":"query","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Public observations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicObservationsResponse"}}}},"400":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/projects":{"get":{"tags":["Projects"],"summary":"List the signed-in developer's projects","operationId":"listProjects","security":[{"developerSession":[]}],"responses":{"200":{"description":"Projects","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectsResponse"}}}},"401":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Projects"],"summary":"Create a project","operationId":"createProject","security":[{"developerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":120},"description":{"type":["string","null"]}}}}}},"responses":{"201":{"description":"Created project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResponse"}}}},"400":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/keys":{"get":{"tags":["Projects"],"summary":"List API keys for owned projects","operationId":"listKeys","security":[{"developerSession":[]}],"parameters":[{"name":"project_id","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Key metadata (never the secret)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeysResponse"}}}}}},"post":{"tags":["Projects"],"summary":"Create an API key","operationId":"createKey","security":[{"developerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["project_id","name"],"properties":{"project_id":{"type":"string","format":"uuid"},"name":{"type":"string","maxLength":120},"environment":{"type":"string","enum":["development","production"]},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/Scope"}},"expires_at":{"type":["string","null"],"format":"date-time"}}}}}},"responses":{"201":{"description":"One-time plaintext key and metadata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedKeyResponse"}}}},"400":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/keys/{id}":{"delete":{"tags":["Projects"],"summary":"Revoke an API key","operationId":"revokeKey","security":[{"developerSession":[]}],"parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Revoked"},"404":{"$ref":"#/components/responses/Error"}}}},"/v1/sources":{"get":{"tags":["Sources"],"summary":"List sources","operationId":"listSources","security":[{"developerSession":[]}],"parameters":[{"name":"project_id","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Sources","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourcesResponse"}}}}}},"post":{"tags":["Sources"],"summary":"Create a source","operationId":"createSource","security":[{"developerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceInput"}}}},"responses":{"201":{"description":"Created source","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceResponse"}}}},"400":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/sources/{id}":{"patch":{"tags":["Sources"],"summary":"Update a source","operationId":"updateSource","security":[{"developerSession":[]}],"parameters":[{"$ref":"#/components/parameters/Id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":120},"description":{"type":["string","null"]},"metadata":{"type":"object"},"status":{"type":"string","enum":["active","disabled"]}}}}}},"responses":{"200":{"description":"Updated source","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceResponse"}}}}}}},"/v1/datasets":{"get":{"tags":["Datasets"],"summary":"List owned datasets","operationId":"listDatasets","security":[{"developerSession":[]}],"parameters":[{"name":"project_id","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Datasets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetsResponse"}}}}}},"post":{"tags":["Datasets"],"summary":"Create a dataset","operationId":"createDataset","security":[{"developerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetInput"}}}},"responses":{"201":{"description":"Created dataset","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetResponse"}}}}}}},"/v1/datasets/{id}":{"patch":{"tags":["Datasets"],"summary":"Update a dataset","operationId":"updateDataset","security":[{"developerSession":[]}],"parameters":[{"$ref":"#/components/parameters/Id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":120},"description":{"type":["string","null"]},"data_license":{"type":["string","null"]},"visibility":{"type":"string","enum":["private","public"]},"status":{"type":"string","enum":["active","archived"]}}}}}},"responses":{"200":{"description":"Updated dataset","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetResponse"}}}}}}},"/v1/datasets/{id}/permissions":{"get":{"tags":["Datasets"],"summary":"List dataset sharing grants","operationId":"listDatasetPermissions","security":[{"developerSession":[]}],"parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermissionsResponse"}}}}}},"post":{"tags":["Datasets"],"summary":"Grant read access to another project","operationId":"createDatasetPermission","security":[{"developerSession":[]}],"parameters":[{"$ref":"#/components/parameters/Id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["grantee_project_id"],"properties":{"grantee_project_id":{"type":"string","format":"uuid"}}}}}},"responses":{"201":{"description":"Permission","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermissionResponse"}}}}}}},"/v1/datasets/{id}/permissions/{granteeProjectId}":{"delete":{"tags":["Datasets"],"summary":"Revoke a dataset sharing grant","operationId":"deleteDatasetPermission","security":[{"developerSession":[]}],"parameters":[{"$ref":"#/components/parameters/Id"},{"name":"granteeProjectId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Revoked"}}}},"/v1/ingest":{"post":{"tags":["Ingest"],"summary":"Ingest one observation","operationId":"ingestObservation","security":[{"apiKey":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObservationInput"}}}},"responses":{"200":{"description":"Duplicate idempotent request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResponse"}}}},"201":{"description":"Stored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResponse"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/ingest/batch":{"post":{"tags":["Ingest"],"summary":"Ingest up to 100 observations","operationId":"ingestBatch","security":[{"apiKey":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["source_id","dataset_id","observations"],"properties":{"source_id":{"type":"string","format":"uuid"},"dataset_id":{"type":"string","format":"uuid"},"observations":{"type":"array","minItems":1,"maxItems":100,"items":{"$ref":"#/components/schemas/IngestItem"}}}}}}},"responses":{"201":{"description":"All observations stored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResponse"}}}},"202":{"description":"Partially accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResponse"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"}}}},"/v1/data":{"get":{"tags":["Data"],"summary":"Read observations allowed by the key's scopes","operationId":"listObservations","security":[{"apiKey":[]}],"parameters":[{"name":"dataset_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"source_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"start","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"end","in":"query","schema":{"type":"string","format":"date-time"}},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"Observations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObservationsResponse"}}}},"403":{"$ref":"#/components/responses/Error"}}}},"/v1/data/{id}":{"get":{"tags":["Data"],"summary":"Read one observation","operationId":"getObservation","security":[{"apiKey":[]}],"parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Observation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObservationResponse"}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/v1/observations":{"get":{"tags":["Data"],"summary":"Read project observations for developer portal data explorer","operationId":"listProjectObservations","security":[{"developerSession":[]}],"parameters":[{"name":"project_id","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"dataset_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"source_id","in":"query","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"Project observations","content":{"application/json":{"schema":{"type":"object","required":["observations"],"properties":{"observations":{"type":"array","items":{"$ref":"#/components/schemas/Observation"}}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/v1/usage":{"get":{"tags":["Usage"],"summary":"Read request usage for owned projects","operationId":"getUsage","security":[{"developerSession":[]}],"parameters":[{"name":"project_id","in":"query","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"Usage rows and total","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"fa_live_...","description":"Project API key. Use Authorization: Bearer fa_live_... or fa_test_...."},"developerSession":{"type":"http","scheme":"bearer","description":"Supabase access token obtained from POST /v1/auth/login."}},"parameters":{"Id":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"Limit":{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":100}},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":200}}},"responses":{"Error":{"description":"Structured error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"TooManyRequests":{"description":"Rate limited or project daily ingestion quota exceeded","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"Scope":{"type":"string","enum":["ingest","read:public","read:private","manage:sources","manage:datasets"]},"Credentials":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":6}}},"SignupCredentials":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8}}},"SessionResponse":{"type":"object","properties":{"success":{"type":"boolean"},"session":{"type":"object","properties":{"access_token":{"type":"string"},"refresh_token":{"type":"string"},"token_type":{"type":"string"},"expires_in":{"type":"integer"},"expires_at":{"type":"integer"},"user":{"type":["object","null"]}}}}},"Measurement":{"type":"object","properties":{"code":{"type":"string"},"unit":{"type":"string"},"description":{"type":["string","null"]},"category":{"type":"string"},"min_value":{"type":["number","null"]},"max_value":{"type":["number","null"]}}},"MeasurementsResponse":{"type":"object","properties":{"success":{"type":"boolean"},"measurements":{"type":"array","items":{"$ref":"#/components/schemas/Measurement"}}}},"Project":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"status":{"type":"string"},"daily_ingest_requests":{"type":"integer","minimum":1,"description":"Daily accepted request budget for this project."},"daily_ingest_rows":{"type":"integer","minimum":1,"description":"Daily accepted observation budget for this project."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"ProjectsResponse":{"type":"object","properties":{"success":{"type":"boolean"},"projects":{"type":"array","items":{"$ref":"#/components/schemas/Project"}}}},"ProjectResponse":{"type":"object","properties":{"success":{"type":"boolean"},"project":{"$ref":"#/components/schemas/Project"}}},"ApiKey":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"project_id":{"type":"string","format":"uuid"},"key_prefix":{"type":"string"},"name":{"type":"string"},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/Scope"}},"environment":{"type":"string"},"expires_at":{"type":["string","null"],"format":"date-time"},"revoked_at":{"type":["string","null"],"format":"date-time"},"last_used_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"KeysResponse":{"type":"object","properties":{"success":{"type":"boolean"},"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}},"CreatedKeyResponse":{"type":"object","properties":{"success":{"type":"boolean"},"api_key":{"type":"string","description":"Shown once; store it immediately."},"key":{"$ref":"#/components/schemas/ApiKey"}}},"Source":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"project_id":{"type":"string","format":"uuid"},"name":{"type":"string"},"source_type":{"type":"string","enum":["station","device","api","simulator","manual"]},"description":{"type":["string","null"]},"metadata":{"type":"object"},"status":{"type":"string","enum":["active","disabled"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"SourceInput":{"type":"object","required":["project_id","name","source_type"],"properties":{"project_id":{"type":"string","format":"uuid"},"name":{"type":"string","maxLength":120},"source_type":{"type":"string","enum":["station","device","api","simulator","manual"]},"description":{"type":["string","null"]},"metadata":{"type":"object"}}},"SourcesResponse":{"type":"object","properties":{"success":{"type":"boolean"},"sources":{"type":"array","items":{"$ref":"#/components/schemas/Source"}}}},"SourceResponse":{"type":"object","properties":{"success":{"type":"boolean"},"source":{"$ref":"#/components/schemas/Source"}}},"Dataset":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"project_id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"visibility":{"type":"string","enum":["public","private"]},"data_license":{"type":["string","null"]},"status":{"type":"string","enum":["active","archived"]},"published_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"DatasetInput":{"type":"object","required":["project_id","name"],"properties":{"project_id":{"type":"string","format":"uuid"},"name":{"type":"string","maxLength":120},"description":{"type":["string","null"]},"data_license":{"type":["string","null"]},"visibility":{"type":"string","enum":["public","private"]}}},"DatasetsResponse":{"type":"object","properties":{"success":{"type":"boolean"},"datasets":{"type":"array","items":{"$ref":"#/components/schemas/Dataset"}}}},"DatasetResponse":{"type":"object","properties":{"success":{"type":"boolean"},"dataset":{"$ref":"#/components/schemas/Dataset"}}},"Permission":{"type":"object","properties":{"dataset_id":{"type":"string","format":"uuid"},"grantee_project_id":{"type":"string","format":"uuid"},"permission":{"type":"string","enum":["read"]},"created_at":{"type":"string","format":"date-time"}}},"PermissionsResponse":{"type":"object","properties":{"success":{"type":"boolean"},"permissions":{"type":"array","items":{"$ref":"#/components/schemas/Permission"}}}},"PermissionResponse":{"type":"object","properties":{"success":{"type":"boolean"},"permission":{"$ref":"#/components/schemas/Permission"}}},"MeasurementValue":{"type":"object","required":["value","unit"],"properties":{"value":{"type":"number"},"unit":{"type":"string"}}},"Location":{"type":"object","required":["latitude","longitude"],"properties":{"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180}}},"ObservationInput":{"type":"object","required":["source_id","dataset_id","timestamp","measurements"],"properties":{"source_id":{"type":"string","format":"uuid"},"dataset_id":{"type":"string","format":"uuid"},"timestamp":{"type":"string","format":"date-time"},"location":{"$ref":"#/components/schemas/Location"},"measurements":{"type":"object","minProperties":1,"additionalProperties":{"$ref":"#/components/schemas/MeasurementValue"}},"metadata":{"type":"object"},"idempotency_key":{"type":"string","maxLength":200}}},"IngestItem":{"type":"object","required":["timestamp","measurements"],"properties":{"timestamp":{"type":"string","format":"date-time"},"location":{"$ref":"#/components/schemas/Location"},"measurements":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MeasurementValue"}},"metadata":{"type":"object"},"idempotency_key":{"type":"string","maxLength":200}}},"Observation":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"dataset_id":{"type":"string","format":"uuid"},"source_id":{"type":"string","format":"uuid"},"observed_at":{"type":"string","format":"date-time"},"latitude":{"type":["number","null"]},"longitude":{"type":["number","null"]},"measurements":{"type":"object"},"metadata":{"type":"object"},"quality_status":{"type":"string"},"received_at":{"type":"string","format":"date-time"}}},"ObservationsResponse":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Observation"}}}},"ObservationResponse":{"type":"object","properties":{"success":{"type":"boolean"},"observation":{"$ref":"#/components/schemas/Observation"}}},"PublicObservationsResponse":{"type":"object","properties":{"success":{"type":"boolean"},"datasets":{"type":"array","items":{"$ref":"#/components/schemas/Dataset"}},"data":{"type":"array","items":{"$ref":"#/components/schemas/Observation"}}}},"IngestResponse":{"type":"object","properties":{"success":{"type":"boolean"},"observation_id":{"type":"string","format":"uuid"},"dataset_id":{"type":"string","format":"uuid"},"source_id":{"type":"string","format":"uuid"},"quality_status":{"type":"string"},"received_at":{"type":"string","format":"date-time"},"duplicate":{"type":"boolean"}}},"BatchResponse":{"type":"object","properties":{"success":{"type":"boolean"},"accepted":{"type":"integer"},"rejected":{"type":"integer"},"duplicates":{"type":"integer"},"total":{"type":"integer"},"results":{"type":"array","items":{"type":"object"}}}},"UsageResponse":{"type":"object","properties":{"success":{"type":"boolean"},"usage":{"type":"array","items":{"type":"object"}},"summary":{"type":"object","properties":{"total_requests":{"type":"integer"}}}}},"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":["object","null"]}}}}}}}}