diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..29b5b77 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +archive/* \ No newline at end of file diff --git a/AGENTS.MD b/AGENTS.MD new file mode 100644 index 0000000..91e15f3 --- /dev/null +++ b/AGENTS.MD @@ -0,0 +1,97 @@ +# Working with the CDS OpenAPI Project + +This document describes how to collaborate with an AI agent (or human contributor) on the `cds-openapi` project. + +## Project Purpose + +This repository maintains an **OpenAPI 3.1 specification** for the [Curb Data Specification (CDS)](https://github.com/openmobilityfoundation/curb-data-specification), managed by the Open Mobility Foundation. The spec is hosted publicly via Stoplight and serves as an interactive API browser for implementers. + +## Repository Structure + +``` +cds-openapi/ + APIs/ + Curbs API.yaml # Curb zones, areas, spaces, policies, objects + Events API.yaml # Curb events and sensor status + Metrics API.yaml # Sessions and aggregates + Shared Data Models/ # Reusable YAML schemas (curb_zone, curb_event, etc.) + Rest Responses/ # Common API response header schemas + toc.json # Stoplight table of contents + .spectral.mjs # Linting rules + .stoplight.json # Stoplight platform config + V1.1_IMPLEMENTATION_PLAN.md # Active implementation plan +``` + +## Branch Strategy + +| Branch | Purpose | +|--------|---------| +| `main` | Stable, latest released version | +| `v1.0` | Frozen v1.0 spec | +| `draft-v1.1` | Active development branch for v1.1 changes | + +Always work on the `draft-v1.1` branch (or a feature branch off it) when implementing v1.1 changes. Never push directly to `main`. + +## Upstream Spec Reference + +The authoritative CDS spec lives at https://github.com/openmobilityfoundation/curb-data-specification. When implementing changes: + +1. Treat the upstream repository's `main` branch as the source of truth for the latest CDS specification +2. Always cross-reference the upstream spec text, not just PR summaries +3. Before editing local OpenAPI files, verify the relevant field names, types, enums, descriptions, and required/optional status against upstream `main` +4. When a discrepancy is found, label it explicitly as local drift, upstream ambiguity, or an inference +5. The spec has three sections: `curbs/`, `events/`, `metrics/` — each with its own README +6. The `general-information.md` and `data-types.md` files contain shared definitions + +## How to Make Changes + +### Workflow for each step in the implementation plan + +1. **Read the plan step** in `V1.1_IMPLEMENTATION_PLAN.md` +2. **Read the upstream spec on `main`** for the relevant section to confirm exact field names, types, enums, descriptions, and required/optional status +3. **Edit the YAML files** — maintain the existing style conventions: + - Use `$ref` for shared models rather than inline definitions + - Include `description` on every field + - Use `x-stoplight: id:` annotations if present on surrounding fields (Stoplight generates these) + - Keep `required` arrays up to date +4. **Validate** — run the Spectral linter (`.spectral.mjs`) after all changes for the task. `spectral` is currently available in this environment, so validation should be performed before wrapping up work. +5. **Update the plan** — use strikethrough in `V1.1_IMPLEMENTATION_PLAN.md` to mark completed items as work lands. Do not add status suffixes like `DONE`, `TODO`, or `Partial` to implementation-step headings. +6. **Commit** — use the commit message suggested in the plan step, or a similar conventional-commit style message + +### Style conventions + +- File names: `snake_case.yaml` for shared models +- Enum values: `snake_case` +- UUID fields: `type: string, format: uuid` +- Timestamps: `$ref: ./timestamp.yaml` +- Geographic fields: `$ref` to `geoJSON_point.yaml`, `geoJSON_polygon.yaml`, or `geoJSON_linestring.yaml` +- Arrays of references: `type: array` with `items: { $ref: ./some_model.yaml }` + +### Adding a new shared model + +1. Create the YAML file in `Shared Data Models/` +2. Add a `$ref` from any model or API that uses it +3. Add an entry to `toc.json` under the appropriate section +4. Verify the `$ref` path is correct relative to the referencing file + +## Validation + +The project uses Spectral for OpenAPI linting: + +```bash +spectral lint "APIs/*.yaml" +``` + +The `.spectral.mjs` config extends a remote Stoplight ruleset. `spectral` is currently available in this workspace and should be run after all changes are made. Always lint and fix any errors before committing. When a task adds or edits standalone shared model files, lint those touched files as well in addition to the API documents. + +## Key Gotchas + +- **$ref paths are relative** to the file containing the reference. API files use `../Shared Data Models/foo.yaml`; shared models use `./foo.yaml`. +- **Spaces in file names**: `Curbs API.yaml` has a space — use URL encoding (`Curbs%20API.yaml`) in Markdown links but literal paths in `$ref`. +- **toc.json** controls what appears in the Stoplight browser — new models won't show up until added here. +- **x-stoplight IDs** are auto-generated by the Stoplight editor. When adding fields by hand, you can omit them and Stoplight will generate them later, or include them for consistency. +- **501 responses** must be documented on all optional endpoints per the CDS spec pattern. + +## Implementation Plan + +The active plan for v1.1 work is in `V1.1_IMPLEMENTATION_PLAN.md`. Follow the phases and steps in order — they are sequenced so that schema dependencies are in place before API paths reference them. diff --git a/APIs/Curbs API.yaml b/APIs/Curbs API.yaml index b022e5c..76cd15b 100644 --- a/APIs/Curbs API.yaml +++ b/APIs/Curbs API.yaml @@ -3,14 +3,34 @@ x-stoplight: id: 83teyinnn1py6 info: title: Curb API - version: '1.0' - description: 'The Curbs API is a REST API allowing cities to specify areas of interest along the curb along with the rules for using them: who is allowed to park, load, unload, pick up, drop off, etc., for how long, for what price (if any), at what times, and on which days. Locations defined in the Curbs API can be connected to event and metrics data, and can be shared with companies and the public, for purposes such as routing, finding legal parking, loading, and pick-up/drop-off spots, or analyzing curb utilization over time.' + version: '1.1' + description: 'The Curbs API is a REST API allowing cities to specify areas of interest along and around the curb, objects in and near the curb or on sidewalks or travel lanes, and off street parking areas. Included are the rules and policies for using these areas: who is allowed to park, load, unload, pick up, drop off, etc., for how long, for what price (if any), at what times, and on which days. Locations defined in the Curbs API can be connected to event and metrics data, and can be shared with companies and the public, for purposes such as routing, finding legal parking, loading, and pick-up/drop-off spots, enforcement, compliance, and analyzing curb utilization over time.' + contact: + name: Open Mobility Foundation + url: 'https://www.openmobilityfoundation.org' + email: membership@openmobilityfoundation.org + license: + name: Creative Commons Attribution 4.0 International Public License + url: 'https://creativecommons.org/licenses/by/4.0/' +tags: + - name: areas + description: Query and fetch curb areas. + - name: objects + description: Query and fetch curb objects. + - name: policies + description: Query and fetch curb policies. + - name: spaces + description: Query and fetch curb spaces. + - name: zones + description: Query and fetch curb zones. servers: - url: 'http://localhost:3000' paths: /curbs/zones: get: summary: Get Curb Zones + tags: + - zones responses: '200': description: Zones Found @@ -18,6 +38,12 @@ paths: application/json: schema: type: object + required: + - version + - time_zone + - last_updated + - currency + - data properties: version: $ref: ../Rest Responses/rest_response_version.yaml @@ -27,24 +53,25 @@ paths: $ref: ../Rest Responses/rest_response_last_updated.yaml currency: $ref: ../Rest Responses/rest_response_currency.yaml + custom_attributes_dictionary: + $ref: ../Rest Responses/rest_response_custom_attributes_dictionary.yaml author: $ref: ../Rest Responses/rest_response_author.yaml license_url: $ref: ../Rest Responses/rest_response_license_url.yaml data: - type: array - items: - type: object - properties: - zones: - type: array - items: - $ref: ../Shared Data Models/curb_zone.yaml + type: object + required: + - zones + properties: + zones: + type: array + items: + $ref: ../Shared Data Models/curb_zone.yaml operationId: get-curbs-zones description: 'This required endpoint must be implemented by every Curbs API server. If attaching policies to curb zones, the Query Curb Policies endpoint is also required.' parameters: - schema: - $ref: '#/components/schemas/uuid' type: string format: uuid in: query @@ -59,7 +86,7 @@ paths: - $ref: '#/components/parameters/radius' - $ref: '#/components/parameters/include_geometry' - schema: - type: string + $ref: ../Shared Data Models/timestamp.yaml in: query name: time description: Only Curb Zone objects whose validity period includes this time will be returned; availability data (if supplied) will be returned as of this time @@ -68,6 +95,8 @@ paths: /curbs/areas: get: summary: Get Curb Areas + tags: + - areas responses: '200': description: Areas Found @@ -75,28 +104,36 @@ paths: application/json: schema: type: object + required: + - version + - time_zone + - last_updated + - currency + - data properties: version: $ref: ../Rest Responses/rest_response_version.yaml time_zone: $ref: ../Rest Responses/rest_response_time_zone.yaml last_updated: - $ref: ../Rest Responses/rest_response_last-updated.yaml + $ref: ../Rest Responses/rest_response_last_updated.yaml currency: $ref: ../Rest Responses/rest_response_currency.yaml + custom_attributes_dictionary: + $ref: ../Rest Responses/rest_response_custom_attributes_dictionary.yaml author: $ref: ../Rest Responses/rest_response_author.yaml license_url: $ref: ../Rest Responses/rest_response_license_url.yaml data: - type: array - items: - type: object - properties: - areas: - type: array - items: - $ref: ../Shared Data Models/curb_area.yaml + type: object + required: + - areas + properties: + areas: + type: array + items: + $ref: ../Shared Data Models/curb_area.yaml '501': description: NOT_IMPLEMENTED operationId: get-curbs-areas @@ -115,6 +152,8 @@ paths: /curbs/spaces: get: summary: Get Curb Spaces + tags: + - spaces responses: '200': description: Spaces Found @@ -122,28 +161,36 @@ paths: application/json: schema: type: object + required: + - version + - time_zone + - last_updated + - currency + - data properties: version: $ref: ../Rest Responses/rest_response_version.yaml time_zone: $ref: ../Rest Responses/rest_response_time_zone.yaml last_updated: - $ref: ../Rest Responses/rest_response_last-updated.yaml + $ref: ../Rest Responses/rest_response_last_updated.yaml currency: $ref: ../Rest Responses/rest_response_currency.yaml + custom_attributes_dictionary: + $ref: ../Rest Responses/rest_response_custom_attributes_dictionary.yaml author: $ref: ../Rest Responses/rest_response_author.yaml license_url: $ref: ../Rest Responses/rest_response_license_url.yaml data: - type: array - items: - type: object - properties: - spaces: - type: array - items: - $ref: ../Shared Data Models/curb_space.yaml + type: object + required: + - spaces + properties: + spaces: + type: array + items: + $ref: ../Shared Data Models/curb_space.yaml '501': description: NOT_IMPLEMENTED operationId: get-curbs-spaces @@ -162,16 +209,139 @@ paths: - $ref: '#/components/parameters/lng' - $ref: '#/components/parameters/radius' - schema: - type: string + $ref: ../Shared Data Models/timestamp.yaml in: query name: time description: Availability data (if supplied) will be returned as of this time. security: [] x-stoplight: id: p8unincykkub4 + /curbs/objects: + get: + summary: Get Curb Objects + tags: + - objects + responses: + '200': + description: Objects Found + content: + application/json: + schema: + type: object + required: + - version + - time_zone + - last_updated + - currency + - data + properties: + version: + $ref: ../Rest Responses/rest_response_version.yaml + time_zone: + $ref: ../Rest Responses/rest_response_time_zone.yaml + last_updated: + $ref: ../Rest Responses/rest_response_last_updated.yaml + currency: + $ref: ../Rest Responses/rest_response_currency.yaml + custom_attributes_dictionary: + $ref: ../Rest Responses/rest_response_custom_attributes_dictionary.yaml + author: + $ref: ../Rest Responses/rest_response_author.yaml + license_url: + $ref: ../Rest Responses/rest_response_license_url.yaml + data: + type: object + required: + - objects + properties: + objects: + type: array + items: + $ref: ../Shared Data Models/curb_object.yaml + '501': + description: NOT_IMPLEMENTED + operationId: get-curbs-objects + description: 'Optional endpoint. If not implemented, the server should reply with 501 Not Implemented.' + parameters: + - schema: + $ref: ../Shared Data Models/timestamp.yaml + in: query + name: time + description: Only the most recently updated objects as of this time will be returned. + - schema: + type: string + format: uuid + in: query + name: zone + description: The ID of a Curb Zone. If specified, only return Curb Objects associated within this zone. + - schema: + type: string + format: uuid + in: query + name: space + description: The ID of a Curb Space. If specified, only return Curb Objects associated within this space. + security: [] + x-stoplight: + id: 5vgp4n8h2j1qd + '/curbs/objects/{id}': + get: + summary: Get a single Curb Object + tags: + - objects + responses: + '200': + description: Object Found + content: + application/json: + schema: + type: object + required: + - version + - time_zone + - last_updated + - currency + - data + properties: + version: + $ref: ../Rest Responses/rest_response_version.yaml + time_zone: + $ref: ../Rest Responses/rest_response_time_zone.yaml + last_updated: + $ref: ../Rest Responses/rest_response_last_updated.yaml + currency: + $ref: ../Rest Responses/rest_response_currency.yaml + custom_attributes_dictionary: + $ref: ../Rest Responses/rest_response_custom_attributes_dictionary.yaml + author: + $ref: ../Rest Responses/rest_response_author.yaml + license_url: + $ref: ../Rest Responses/rest_response_license_url.yaml + data: + $ref: ../Shared Data Models/curb_object.yaml + '501': + description: NOT_IMPLEMENTED + operationId: get-curbs-object + description: 'Fetch a single Curb Object by ID. Optional endpoint. If not implemented, the server should reply with 501 Not Implemented.' + parameters: + - schema: + type: string + name: id + in: path + required: true + description: Curb Object ID + - schema: + $ref: ../Shared Data Models/timestamp.yaml + in: query + name: time + description: Availability data (if supplied) will be returned as of this time. + security: [] + x-stoplight: + id: 2q7b9n4d5k1mv /curbs/policies: get: summary: Get Curb Policies + tags: + - policies responses: '200': description: Policies Found @@ -179,39 +349,53 @@ paths: application/json: schema: type: object + required: + - version + - time_zone + - last_updated + - currency + - data properties: version: $ref: ../Rest Responses/rest_response_version.yaml time_zone: $ref: ../Rest Responses/rest_response_time_zone.yaml last_updated: - $ref: ../Rest Responses/rest_response_last-updated.yaml + $ref: ../Rest Responses/rest_response_last_updated.yaml currency: $ref: ../Rest Responses/rest_response_currency.yaml + custom_attributes_dictionary: + $ref: ../Rest Responses/rest_response_custom_attributes_dictionary.yaml author: $ref: ../Rest Responses/rest_response_author.yaml license_url: $ref: ../Rest Responses/rest_response_license_url.yaml data: - type: array - items: - type: object - properties: - policies: - type: array - items: - $ref: ../Shared Data Models/curb_policy.yaml + type: object + required: + - policies + properties: + policies: + type: array + items: + $ref: ../Shared Data Models/curb_policy.yaml '501': description: NOT_IMPLEMENTED operationId: get-curbs-policies description: 'Optional endpoint, but required if Curb Zones contain policy_id references. If not implemented, the server should reply with 501 Not Implemented.' parameters: - schema: - type: string - format: uuid - example: '1111ad2f-14ef-40c1-b8d9-b974c89f7fa9,884d11b8-4fb7-42f2-a3ee-6c4b7499c2b3' + type: array + items: + type: string + format: uuid + example: + - 1111ad2f-14ef-40c1-b8d9-b974c89f7fa9 + - 884d11b8-4fb7-42f2-a3ee-6c4b7499c2b3 in: query name: ids + style: form + explode: false description: 'If present, return only policies with the supplied UUIDs. Otherwise, return all policies.' security: [] x-stoplight: @@ -219,6 +403,8 @@ paths: '/curbs/zones/{id}': get: summary: Get a single Curb Zone + tags: + - zones responses: '200': description: Zone Found @@ -226,15 +412,23 @@ paths: application/json: schema: type: object + required: + - version + - time_zone + - last_updated + - currency + - data properties: version: $ref: ../Rest Responses/rest_response_version.yaml time_zone: $ref: ../Rest Responses/rest_response_time_zone.yaml last_updated: - $ref: ../Rest Responses/rest_response_last-updated.yaml + $ref: ../Rest Responses/rest_response_last_updated.yaml currency: $ref: ../Rest Responses/rest_response_currency.yaml + custom_attributes_dictionary: + $ref: ../Rest Responses/rest_response_custom_attributes_dictionary.yaml author: $ref: ../Rest Responses/rest_response_author.yaml license_url: @@ -253,8 +447,7 @@ paths: required: true description: Curb Zone ID - schema: - $ref: '#/components/schemas/timestamp' - type: string + $ref: ../Shared Data Models/timestamp.yaml in: query name: time description: 'The Curb Zone object will only be returned if its validity period includes this time; otherwise, the server should reply with `404 Not Found`.' @@ -269,6 +462,8 @@ paths: '/curbs/areas/{id}': get: summary: Get a single Curb Area + tags: + - areas responses: '200': description: Area Found @@ -276,15 +471,23 @@ paths: application/json: schema: type: object + required: + - version + - time_zone + - last_updated + - currency + - data properties: version: $ref: ../Rest Responses/rest_response_version.yaml time_zone: $ref: ../Rest Responses/rest_response_time_zone.yaml last_updated: - $ref: ../Rest Responses/rest_response_last-updated.yaml + $ref: ../Rest Responses/rest_response_last_updated.yaml currency: $ref: ../Rest Responses/rest_response_currency.yaml + custom_attributes_dictionary: + $ref: ../Rest Responses/rest_response_custom_attributes_dictionary.yaml author: $ref: ../Rest Responses/rest_response_author.yaml license_url: @@ -308,6 +511,8 @@ paths: '/curbs/spaces/{id}': get: summary: Get a single Curb Space + tags: + - spaces responses: '200': description: Space Found @@ -315,15 +520,23 @@ paths: application/json: schema: type: object + required: + - version + - time_zone + - last_updated + - currency + - data properties: version: $ref: ../Rest Responses/rest_response_version.yaml time_zone: $ref: ../Rest Responses/rest_response_time_zone.yaml last_updated: - $ref: ../Rest Responses/rest_response_last-updated.yaml + $ref: ../Rest Responses/rest_response_last_updated.yaml currency: $ref: ../Rest Responses/rest_response_currency.yaml + custom_attributes_dictionary: + $ref: ../Rest Responses/rest_response_custom_attributes_dictionary.yaml author: $ref: ../Rest Responses/rest_response_author.yaml license_url: @@ -342,8 +555,7 @@ paths: required: true description: Curb Space ID - schema: - $ref: '#/components/schemas/timestamp' - type: string + $ref: ../Shared Data Models/timestamp.yaml in: query name: time description: Availability data (if supplied) will be returned as of this time. @@ -353,6 +565,8 @@ paths: '/curbs/policies/{id}': get: summary: Get a single Curb Policy + tags: + - policies responses: '200': description: Policy Found @@ -360,15 +574,23 @@ paths: application/json: schema: type: object + required: + - version + - time_zone + - last_updated + - currency + - data properties: version: $ref: ../Rest Responses/rest_response_version.yaml time_zone: $ref: ../Rest Responses/rest_response_time_zone.yaml last_updated: - $ref: ../Rest Responses/rest_response_last-updated.yaml + $ref: ../Rest Responses/rest_response_last_updated.yaml currency: $ref: ../Rest Responses/rest_response_currency.yaml + custom_attributes_dictionary: + $ref: ../Rest Responses/rest_response_custom_attributes_dictionary.yaml author: $ref: ../Rest Responses/rest_response_author.yaml license_url: @@ -376,9 +598,9 @@ paths: data: $ref: ../Shared Data Models/curb_policy.yaml '501': - description: Not Implemented + description: NOT_IMPLEMENTED operationId: get-curbs-policy - description: Fetch a single Curb Policy by ID. + description: 'Fetch a single Curb Policy by ID. Optional endpoint. If not implemented, the server should reply with 501 Not Implemented.' parameters: - schema: type: string @@ -440,42 +662,7 @@ components: required: false schema: type: number - description: 'Specifies a latitude and longitude bounding point and a radius away from that point. Must be used together with `lng` and `lng`. Returns only locations that are within radius centimeters of the point identified by lat/lng. Curb Zones in the response MUST be ordered ascending by distance from the center point. This parameter is incompatible with `min_lat`, `min_lng`, `max_lat`, and `max_lng`' - start_time: - name: start_time - in: query - required: false - schema: - type: string - description: The start of the time period to return data where the value is inclusive. - end_time: - name: end_time - in: query - required: false - schema: - type: string - description: The end of the time period to return data where the value is inclusive. - curb_area_id: - name: curb_area_id - in: query - required: false - schema: - type: string - description: 'The ID of a Curb Area. If specified, only return records occurring within this area.' - curb_zone_id: - name: curb_zone_id - in: query - required: false - schema: - type: string - description: 'The ID of a Curb Zone. If specified, only return records occurring within this zone.' - curb_space_id: - name: curb_space_id - in: query - required: false - schema: - type: string - description: 'The ID of a Curb Space. If specified, only return records occurring within this area.' + description: 'Specifies a latitude and longitude bounding point and a radius away from that point. Must be used together with `lat` and `lng`. Returns only locations that are within radius centimeters of the point identified by lat/lng. Curb Zones in the response MUST be ordered ascending by distance from the center point. This parameter is incompatible with `min_lat`, `min_lng`, `max_lat`, and `max_lng`' include_geometry: name: include_geometry in: query diff --git a/APIs/Events API.yaml b/APIs/Events API.yaml index 428b2f4..99c35ce 100644 --- a/APIs/Events API.yaml +++ b/APIs/Events API.yaml @@ -3,15 +3,28 @@ x-stoplight: id: i4ivj21etaicj info: title: Event API - version: '1.0' + version: '1.1' description: 'The Events API is a REST API allowing real-time and historic events at the curb to be sent to cities, and the ability to check on the status of any sensors. Events can come from company data feeds, on street sensors, session payments, company check-ins, in-person parking personnel, and/or other city data sources. Data sent in the Events API can be connected to the Curbs API over time and space, and events are used for calculations in the Metrics API.' + contact: + name: Open Mobility Foundation + url: 'https://www.openmobilityfoundation.org' + email: membership@openmobilityfoundation.org + license: + name: Creative Commons Attribution 4.0 International Public License + url: 'https://creativecommons.org/licenses/by/4.0/' +tags: + - name: events + description: Query curb events. + - name: status + description: Query curb sensor and source status. servers: - url: 'http://localhost:3000' paths: /events/events: get: summary: Get Events - tags: [] + tags: + - events responses: '200': description: OK @@ -20,6 +33,12 @@ paths: application/json: schema: type: object + required: + - version + - time_zone + - last_updated + - currency + - data properties: version: $ref: ../Rest Responses/rest_response_version.yaml @@ -37,6 +56,8 @@ paths: $ref: ../Rest Responses/rest_response_currency.yaml x-stoplight: id: ez7o2wgpfn60b + custom_attributes_dictionary: + $ref: ../Rest Responses/rest_response_custom_attributes_dictionary.yaml author: $ref: ../Rest Responses/rest_response_author.yaml x-stoplight: @@ -49,6 +70,8 @@ paths: type: object x-stoplight: id: fhxkczml8n5d5 + required: + - events properties: events: type: array @@ -62,14 +85,26 @@ paths: x-stoplight: id: er2r1dx6pype6 parameters: + - schema: + type: string + in: query + name: event_time + description: An ISO 8601 extended datetime representing a UTC hour between 00 and 23 in `YYYY-MM-DDTHH` format. If omitted, return all events from the last 60 minutes. For example, `event_time=2019-10-01T07` returns events where `2019-10-01T07:00:00 <= event.event_time < 2019-10-01T08:00:00` UTC. - $ref: '#/components/parameters/curb_area_id' - $ref: '#/components/parameters/curb_zone_id' - $ref: '#/components/parameters/curb_space_id' - description: This required endpoint must be implemented by every Events API server. Enables the querying of CDS events. + - $ref: '#/components/parameters/curb_object_id' + security: + - bearerAuth: [] + - {} + description: |- + Authorization is recommended for this endpoint. + This required endpoint must be implemented by every Events API server. It returns CDS events ordered by `event_time`, with the newest events first, following the Event Times guidance. /events/status: get: summary: Get Status - tags: [] + tags: + - status responses: '200': description: OK @@ -77,6 +112,12 @@ paths: application/json: schema: type: object + required: + - version + - time_zone + - last_updated + - currency + - data properties: version: $ref: ../Rest Responses/rest_response_version.yaml @@ -106,6 +147,8 @@ paths: type: object x-stoplight: id: e1wkbj37xvkz9 + required: + - status properties: status: type: array @@ -124,10 +167,165 @@ paths: - $ref: '#/components/parameters/curb_area_id' - $ref: '#/components/parameters/curb_zone_id' - $ref: '#/components/parameters/curb_space_id' - description: Optional endpoint. Enables the querying of statuses for various sensors monitoring curb places. + - $ref: '#/components/parameters/curb_object_id' + security: + - bearerAuth: [] + - {} + description: |- + Authorization is recommended for this endpoint. + Optional endpoint. Enables the querying of statuses for various sensors monitoring curb places. If not implemented, the server should reply with `501 Not Implemented`. + /events/event: + post: + summary: Push Event + tags: + - events + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/event_batch_request' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/event_bulk_response' + '201': + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/event_bulk_response' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/event_error_response' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/event_error_response' + '404': + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/event_error_response' + '406': + description: Not Acceptable + content: + application/json: + schema: + $ref: '#/components/schemas/event_error_response' + '409': + description: Conflict + content: + application/json: + schema: + $ref: '#/components/schemas/event_error_response' + '500': + description: Internal Server Error. The response may contain a plain-text error message for troubleshooting. + content: + application/json: + schema: + $ref: '#/components/schemas/event_error_response' + text/plain: + schema: + type: string + '501': + description: Not Implemented + operationId: post-events-event + description: |- + Authorization is required for this endpoint. + Optional endpoint. Enables submission of CDS events. If not implemented, the server should reply with `501 Not Implemented`. Servers implementing this endpoint should deduplicate events from a publisher based on the `event_id` field, and should expect repeated submissions after interrupted network or system connections. components: - schemas: {} + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + description: Bearer token authentication. JWT is recommended as the token format. + schemas: + event_batch_request: + type: array + description: Array of Curb Event objects to submit to `POST /events/event`. + items: + $ref: ../Shared Data Models/curb_event.yaml + event_bulk_failure: + type: object + description: Details for one failed item in a bulk event submission response. + required: + - item + - error + - error_description + properties: + item: + $ref: ../Shared Data Models/curb_event.yaml + description: The submitted event that failed processing. + error: + type: string + description: Short machine-readable error code for the failed item. + error_description: + type: string + description: Human-readable explanation of why the item failed. + error_details: + type: array + description: Array of field names or other details that explain the failure. + items: + type: string + event_bulk_response: + type: object + description: Bulk response for multi-record `POST /events/event` submissions. `success` counts written records, `total` counts submitted records, and `failures` lists item-level errors. + required: + - success + - total + - failures + properties: + success: + type: integer + description: Number of successfully written records. + total: + type: integer + description: Total number of records submitted. + failures: + type: array + description: Array of failed records. The array is empty when every item succeeds. + items: + $ref: '#/components/schemas/event_bulk_failure' + event_error_response: + type: object + description: Generic Events API error response object. The `error` field is a machine-readable error code, `error_description` is a human-readable explanation, and `error_details` provides additional troubleshooting context. + required: + - error + - error_description + properties: + error: + type: string + description: Error code such as `bad_param` or `missing_param`. + error_description: + type: string + description: Human-readable error description. This may be localized. + error_details: + type: array + description: Array of error details, such as missing parameters or field names. + items: + type: string parameters: + curb_object_id: + name: curb_object_id + in: query + required: false + schema: + type: string + format: uuid + description: The ID of a Curb Object. If specified, only return events or statuses occurring at this object. curb_area_id: name: curb_area_id in: query diff --git a/APIs/Metrics API.yaml b/APIs/Metrics API.yaml index e62f723..582178f 100644 --- a/APIs/Metrics API.yaml +++ b/APIs/Metrics API.yaml @@ -3,48 +3,46 @@ x-stoplight: id: 2p76lk7uckivl info: title: Metrics API - version: '1.0' - description: 'The Metrics API is a REST API allowing historic metrics calculations based on Event activity that happened at defined Curb places. Defines common calculation methodologies to measure historic dwell time, occupancy, usage and other aggregated statistics.' + version: '1.1' + description: 'The Metrics API is a REST API allowing historic metrics calculations based on Event activity that happened at defined Curb places. Metrics data should be viewed as representative sample data, not necessarily a 100% accurate picture of what happens at every defined curb space, and agencies may update the data monthly or more frequently depending on their implementation. Defines common calculation methodologies to measure historic dwell time, occupancy, usage and other aggregated statistics.' + contact: + name: Open Mobility Foundation + url: 'https://www.openmobilityfoundation.org' + email: membership@openmobilityfoundation.org + license: + name: Creative Commons Attribution 4.0 International Public License + url: 'https://creativecommons.org/licenses/by/4.0/' +tags: + - name: aggregates + description: Query aggregated curb metrics. + - name: sessions + description: Query curb metric sessions. servers: - url: 'http://localhost:3000' paths: /metrics/sessions: get: summary: Get Metric Sessions - tags: [] + tags: + - sessions + description: |- + Optional endpoint. Authorization is recommended for all Metrics endpoints, since depending on implementation, use cases, fields required, local laws, and audience it may contain information only city transportation agencies should have access to. + + Metrics data should be viewed as representative sample data, not necessarily a 100% accurate picture of what happens at every defined curb space. Agencies may choose how frequently they update the data; at least monthly is recommended, but weekly, daily, hourly, or more frequent updates are acceptable. + + Agencies wishing to publicly release Metrics data are encouraged to limit releases to static Aggregate data that has been reviewed for potential privacy risks. + + An agency may choose to make this endpoint static (and return all the available data at once in a single file) or dynamic (and allow the use of any or all of the query parameters below to filter the data). If dynamic, all query parameters are optional. If not implemented, a server should reply with 501 Not Implemented. responses: '200': - description: OK + description: CSV file content: - application/json: + application/vnd.cds+csv;version=1.1: schema: - type: object - properties: - version: - $ref: ../Rest Responses/rest_response_version.yaml - time_zone: - $ref: ../Rest Responses/rest_response_time_zone.yaml - last_updated: - $ref: ../Rest Responses/rest_response_last_updated.yaml - currency: - $ref: ../Rest Responses/rest_response_currency.yaml - author: - $ref: ../Rest Responses/rest_response_author.yaml - license_url: - $ref: ../Rest Responses/rest_response_license_url.yaml - data: - type: object - x-stoplight: - id: 6hdpx6vi33ec9 - properties: - sessions: - type: array - x-stoplight: - id: je2bc2zsqo5jk - items: - $ref: ../Shared Data Models/session.yaml - x-stoplight: - id: 69aplzzla18wd + type: string + description: CSV rows corresponding to the Session data object. + '406': + description: Not Acceptable '501': description: Not Implemented operationId: get-metrics-sessions @@ -62,47 +60,29 @@ paths: - $ref: '#/components/parameters/radius' - $ref: '#/components/parameters/start_time' - $ref: '#/components/parameters/end_time' - description: |- - Optional endpoint. Enables the querying of sessions from an agency. - - An agency may choose to make this endpoint static (and return all the available data at once in a single file) or dynamic (and allow the use of any or all of the query parameters below to filter the data). If dynamic, all query parameters are optional. /metrics/aggregates: get: summary: Get Metric Aggregates - tags: [] + tags: + - aggregates + description: |- + Optional endpoint. Authorization is recommended for all Metrics endpoints, since depending on implementation, use cases, fields required, local laws, and audience it may contain information only city transportation agencies should have access to. + + Metrics data should be viewed as representative sample data, not necessarily a 100% accurate picture of what happens at every defined curb space. Agencies may choose how frequently they update the data; at least monthly is recommended, but weekly, daily, hourly, or more frequent updates are acceptable. + + Agencies wishing to publicly release Metrics data are encouraged to limit releases to static Aggregate data that has been reviewed for potential privacy risks. + + An agency may choose to make this endpoint static (and return all the available data at once in a single file) or dynamic (and allow the use of any or all of the query parameters below to filter the data). If dynamic, all query parameters are optional. If not implemented, a server should reply with 501 Not Implemented. responses: '200': - description: OK + description: CSV file content: - application/json: + application/vnd.cds+csv;version=1.1: schema: - type: object - properties: - version: - $ref: ../Rest Responses/rest_response_version.yaml - time_zone: - $ref: ../Rest Responses/rest_response_time_zone.yaml - last_updated: - $ref: ../Rest Responses/rest_response_last_updated.yaml - currency: - $ref: ../Rest Responses/rest_response_currency.yaml - author: - $ref: ../Rest Responses/rest_response_author.yaml - license_url: - $ref: ../Rest Responses/rest_response_license_url.yaml - data: - type: object - x-stoplight: - id: zb3228zd0gb2t - properties: - aggregate: - type: array - x-stoplight: - id: 3b1l6aypuq5sc - items: - $ref: ../Shared Data Models/aggregate.yaml - x-stoplight: - id: w9zfx39ouf3ti + type: string + description: CSV rows corresponding to the Aggregate data object. + '406': + description: Not Acceptable '501': description: Not Implemented operationId: get-metrics-aggregates @@ -121,12 +101,6 @@ paths: - $ref: '#/components/parameters/radius' - $ref: '#/components/parameters/start_time' - $ref: '#/components/parameters/end_time' - requestBody: - content: {} - description: |- - Optional endpoint. Enables the querying of aggregates from an agency. - - An agency may choose to make this endpoint static (and return all the available data at once in a single file) or dynamic (and allow the use of any or all of the query parameters below to filter the data). If dynamic, all query parameters are optional. components: schemas: {} parameters: @@ -143,56 +117,56 @@ components: required: false schema: type: number - description: 'Used to specify a latitude and longitude bounding box. Must be used together with `min_lat`, `max_lat`, and `max_lng`. If specified only return locations that intersect the supplied bounding box. This parameter is incompatible with `lat`, `lng`, and `radius`.' + description: 'Used to specify a latitude and longitude bounding box. Must be used together with `min_lat`, `max_lat`, and `max_lng`. If specified only return locations that intersect the supplied bounding box. This parameter is incompatible with `lat`, `lng`, and `radius`.' max_lat: name: max_lat in: query required: false schema: type: number - description: 'Used to specify a latitude and longitude bounding box. Must be used together with `min_lat`, `min_lng`, and `max_lng`. If specified only return locations that intersect the supplied bounding box. This parameter is incompatible with `lat`, `lng`, and `radius`.' + description: 'Used to specify a latitude and longitude bounding box. Must be used together with `min_lat`, `min_lng`, and `max_lng`. If specified only return locations that intersect the supplied bounding box. This parameter is incompatible with `lat`, `lng`, and `radius`.' max_lng: name: max_lng in: query required: false schema: type: number - description: 'Used to specify a latitude and longitude bounding box. Must be used together with `min_lat`, `min_lng`, and `max_lat`. If specified only return locations that intersect the supplied bounding box. This parameter is incompatible with `lat`, `lng`, and `radius`.' + description: 'Used to specify a latitude and longitude bounding box. Must be used together with `min_lat`, `min_lng`, and `max_lat`. If specified only return locations that intersect the supplied bounding box. This parameter is incompatible with `lat`, `lng`, and `radius`.' lat: name: lat in: query required: false schema: type: number - description: 'Specifies a latitude and longitude bounding point and a radius away from that point. Must be used together with `lng` and `radius`. Returns only locations that are within radius centimeters of the point identified by lat/lng. Curb Zones in the response MUST be ordered ascending by distance from the center point. This parameter is incompatible with `min_lat`, `min_lng`, `max_lat`, and `max_lng`' + description: 'Specifies a latitude and longitude bounding point and a radius away from that point. Must be used together with `lng` and `radius`. Returns only locations that are within radius centimeters of the point identified by lat/lng. Curb Zones in the response MUST be ordered ascending by distance from the center point. This parameter is incompatible with `min_lat`, `min_lng`, `max_lat`, and `max_lng`.' lng: name: lng in: query required: false schema: type: number - description: 'Specifies a latitude and longitude bounding point and a radius away from that point. Must be used together with `lat` and `radius`. Returns only locations that are within radius centimeters of the point identified by lat/lng. Curb Zones in the response MUST be ordered ascending by distance from the center point. This parameter is incompatible with `min_lat`, `min_lng`, `max_lat`, and `max_lng`' + description: 'Specifies a latitude and longitude bounding point and a radius away from that point. Must be used together with `lat` and `radius`. Returns only locations that are within radius centimeters of the point identified by lat/lng. Curb Zones in the response MUST be ordered ascending by distance from the center point. This parameter is incompatible with `min_lat`, `min_lng`, `max_lat`, and `max_lng`.' radius: name: radius in: query required: false schema: type: number - description: 'Specifies a latitude and longitude bounding point and a radius away from that point. Must be used together with `lng` and `lng`. Returns only locations that are within radius centimeters of the point identified by lat/lng. Curb Zones in the response MUST be ordered ascending by distance from the center point. This parameter is incompatible with `min_lat`, `min_lng`, `max_lat`, and `max_lng`' + description: 'Specifies a latitude and longitude bounding point and a radius away from that point. Must be used together with `lat` and `lng`. Returns only locations that are within radius centimeters of the point identified by lat/lng. Curb Zones in the response MUST be ordered ascending by distance from the center point. This parameter is incompatible with `min_lat`, `min_lng`, `max_lat`, and `max_lng`.' start_time: name: start_time in: query required: false schema: - type: string - description: The start of the time period to return data where the value is inclusive. + $ref: ../Shared Data Models/timestamp.yaml + description: The start of the time period to return data; the value is inclusive. end_time: name: end_time in: query required: false schema: - type: string - description: The end of the time period to return data where the value is inclusive. + $ref: ../Shared Data Models/timestamp.yaml + description: The end of the time period to return data; the value is exclusive. curb_place_type: name: curb_place_type in: query @@ -203,7 +177,8 @@ components: - area - zone - space - description: The type of curb place this aggregate applies to from the Curbs API. + - object + description: The type of curb place this aggregate applies to from the Curbs API. Required with `curb_place_id`. curb_place_id: name: curb_place_id in: query @@ -211,7 +186,7 @@ components: schema: type: string format: uuid - description: 'The ID of this single curb place. If specified, only return data contained within this area. Required with `curb_place_type`.' + description: The ID of this single curb place. If specified, only return data contained within this curb place. Required with `curb_place_type`. metric_type: name: metric_type in: query @@ -220,7 +195,8 @@ components: type: string enum: - total_sessions + - total_events - turnover - average_dwell_time - occupancy_percent - description: 'The single metric to return from the [Methodology](https://github.com/openmobilityfoundation/curb-data-specification/tree/main/metrics#methodology)' + description: 'The single metric to return from the [Methodology](https://github.com/openmobilityfoundation/curb-data-specification/tree/main/metrics#methodology).' diff --git a/CHANGELOG.MD b/CHANGELOG.MD new file mode 100644 index 0000000..4ec9cb6 --- /dev/null +++ b/CHANGELOG.MD @@ -0,0 +1,98 @@ +# CDS OpenAPI – Change Log + +This change log tracks how the CDS **OpenAPI schema** (this repo) reflects changes in the upstream +[CDS specification](https://github.com/openmobilityfoundation/curb-data-specification). + +--- + +## [1.1.0] – 2025-10-27 + +**Upstream spec:** CDS 1.1.0 ([release notes](https://github.com/openmobilityfoundation/curb-data-specification/releases/tag/1.1.0)) +**Upstream PR:** [#201](https://github.com/openmobilityfoundation/curb-data-specification/pull/201) + +### New Data Models + +- **Curb Object** — new first-class model for physical infrastructure at or near the curb (bollards, planters, cameras, pay stations, lockers, etc.) with Point and LineString geometry, ownership, policy references, and external links. +- **Enforcement** — nested object on events capturing enforcement actions with citation IDs, warning flags, action taken, and cost. +- **Violation** — nested object within enforcement for individual violation codes, names, and costs. +- **Payment Channel** — enum for payment medium (meter, mobile_app, website, sms, telephone). +- **Payment Method** — enum for payment instrument (cash, credit_card, debit_card, digital_wallet, transit_card, prepaid_account, permit). + +### New API Endpoints + +- `GET /curbs/objects` — query curb objects by area, zone, space, time, and operator. +- `GET /curbs/objects/{id}` — fetch a single curb object by ID. +- `POST /events/events` — optional push endpoint for submitting events in real time. + +### Curb Event Changes + +- Add `payment_channel`, `payment_method`, `payment_transaction_id` fields. +- Add `enforcement` object (with nested violations). +- Add `curb_object_id` reference. +- Add vehicle computer-vision fields: `vehicle_license_plate_jurisdiction`, `vehicle_license_plate_confidence`, `vehicle_type_confidence`, `vehicle_color`, `vehicle_color_confidence`, `vehicle_company_name`, `vehicle_company_name_confidence`, `vehicle_run_id`, `vehicle_run_id_confidence`. +- Add `data_source_device_name`. +- Add `vehicle_type` as a direct field reference. +- Add `event_time` query parameter to `GET /events/events` (ISO 8601 UTC hour format). + +### Curb Zone Changes + +- Add optional `geometry_line` (GeoJSON LineString) alongside the existing polygon geometry. +- Add `curb_object_ids` array linking zones to physical objects. +- Add context fields: `description`, `jurisdiction_type` (public/private/other), `owner_name`, `address_number`. +- Add `external_references` and `custom_attributes`. + +### Curb Space Changes + +- Add `curb_object_ids` array (conditionally required). +- Add `external_references` and `custom_attributes`. + +### Curb Area Changes + +- Add `external_references` and `custom_attributes`. + +### Policy & Rule Changes + +- Add `name`, `description`, and `primary_color` to curb policies. +- Loosen priority constraint: overlapping policies may share priority if they apply to disjoint user classes or activities. +- Add `name` and `description` to rules. + +### Temporal Changes + +- Add `weeks_of_month` to time spans for week-of-month scheduling. +- Update `designated_period_except` behavior per v1.1 guidance. +- Fix `days_of_week` from single string to array type. + +### Enumeration Updates + +- **Event types:** add `vehicle_detected`, `vehicle_violation_start`, `vehicle_violation_end`, `citation_issued`. +- **Vehicle types:** add `bus`, `delivery_robot`, `scooter_standing`, `scooter_seated`; fix `bicyle` → `bicycle`. +- **Propulsion types:** add `combustion_diesel`, `hybrid`, `hydrogen_fuel_cell`, `plug_in_hybrid`. +- **User classes (rules):** replace `handicap-accessible` with `accessible`; add `disabled_parking_permit`. + +### External References + +- Add reusable `external_reference` schema for linking CDS data to external systems (WZDx, CWZ, MDS, GBFS, GTFS, websites, documents). +- Wire `external_references` array onto curb zones, areas, spaces, events, policies, and objects. + +### Custom Attributes + +- Add reusable `custom_attributes` schema for implementation-specific key/value data. +- Wire onto curb zones, areas, spaces, events, policies, sessions, aggregates, and objects. + +### Metrics Changes + +- Add `curb_object_id` to session model. +- Add enforcement-related metric types to aggregates (e.g., `total_events`, `total_enforcement_events`). + +### Authorization & API Behavior + +- Clarify that Curbs and Events endpoints may require authorization by the public agency. +- Event authorization is recommended but not required, allowing public event data. +- Standardize 501 Not Implemented responses on all optional endpoints. +- Add `operator` query parameter to Curbs API endpoints. + +--- + +## [1.0.0] + +Initial OpenAPI 3.1 specification for CDS 1.0. See the `v1.0` branch for this version. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..b9399e8 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,18 @@ +# CLAUDE.md + +Read [AGENTS.MD](AGENTS.MD) for full project context, structure, conventions, and workflow instructions. + +## Quick Reference + +- **What this repo is:** OpenAPI 3.1 spec for the Curb Data Specification (CDS) +- **Active branch:** `draft-v1.1` +- **Implementation plan:** [V1.1_IMPLEMENTATION_PLAN.md](V1.1_IMPLEMENTATION_PLAN.md) +- **Upstream spec:** https://github.com/openmobilityfoundation/curb-data-specification +- **Upstream PR for v1.1 changes:** https://github.com/openmobilityfoundation/curb-data-specification/pull/201 + +## Before making any changes + +1. Confirm you are on the `draft-v1.1` branch +2. Read the relevant step in `V1.1_IMPLEMENTATION_PLAN.md` +3. Cross-reference the upstream CDS spec for exact field definitions +4. After editing, validate with the Spectral linter diff --git a/README.md b/README.md index 2ef30b3..cca96b2 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # CDS OpenAPI -**Status: Approved for v1.0** +**Status: Draft In Progress for v1.1** -_Last updated on Feb 9 2024_ +_Last updated April 7, 2026_ --- ## Overview @@ -16,7 +16,7 @@ Interactive OpenAPI documentation for the CDS APIs is visible on Stoplight's [OM The CDS schema versions are documented as different branches in the underlying GitHub project repo. The branch naming will only include the major and minor semantic versions. ### Public Releases -Any work on future releases of CDS will be completed in a development branch and will be identified by the `-dev` suffix in the repo name. For example, as CDS version 1.0 is available, users may view this version of the OpenAPI schema by choosing the `v1.0` branch. +Any work on future releases of CDS will be completed in a development branch and will be identified by the `dev-` prefix in the repo name. For example, as CDS version 1.0 is available, users may view this version of the OpenAPI schema by choosing the `v1.0` branch. ### Upcoming Releases -After the ratification and approval of a new version, such as CDS v1.1, a `v1.1-dev` branch will be created to demonstrate it is a work in progress. Once complete, the `v1.1-dev` branch will be merged into a `v1.1` branch and the latest version of the spec will exist within the `main` branch of the repo. +After the ratification and approval of a new version, such as CDS v1.1, a `draft-v1.1` branch will be created to demonstrate it is a work in progress. Once complete, the `draft-v1.1` branch will be merged into a `v1.1` branch and the latest version of the spec will exist within the `main` branch of the repo. diff --git a/Rest Responses/rest_response_currency.yaml b/Rest Responses/rest_response_currency.yaml index 0cb1e1a..965d7ad 100644 --- a/Rest Responses/rest_response_currency.yaml +++ b/Rest Responses/rest_response_currency.yaml @@ -6,4 +6,4 @@ description: |- This is a standard value that must be returned in the body of all API endpoints. The ISO 4217 3-letter code for the currency in which rates for curb usage are denominated. All costs should be given as integers in the currency's smallest unit. As an example, to represent `$1 USD`, specify an amount of `100` (for 100 cents). -example: '100' +example: USD diff --git a/Rest Responses/rest_response_custom_attributes_dictionary.yaml b/Rest Responses/rest_response_custom_attributes_dictionary.yaml new file mode 100644 index 0000000..238c09e --- /dev/null +++ b/Rest Responses/rest_response_custom_attributes_dictionary.yaml @@ -0,0 +1,13 @@ +title: Custom Attributes Dictionary +x-stoplight: + id: nq1l5v6u0c6hp +type: string +format: uri +description: |- + This is a standard value that may be returned in the body of JSON API endpoints. + + A URL to the data dictionary containing information about the fields and values + used in `custom_attributes`. This should describe the attribute name, data + type, associated CDS element if applicable, and what the attribute represents. + Use `custom_attributes_dictionary` consistently when this field is included. +example: https://city.example.gov/cds/custom-attributes-dictionary.json diff --git a/Rest Responses/rest_response_version.yaml b/Rest Responses/rest_response_version.yaml index fbe48dd..cf0445b 100644 --- a/Rest Responses/rest_response_version.yaml +++ b/Rest Responses/rest_response_version.yaml @@ -6,4 +6,4 @@ description: |- This is a standard value that must be returned in the body of all API endpoints. The version of CDS that the API conforms to. -example: 1.0.0 +example: 1.1.0 diff --git a/Shared Data Models/aggregate.yaml b/Shared Data Models/aggregate.yaml index 12541a3..5ae7e9e 100644 --- a/Shared Data Models/aggregate.yaml +++ b/Shared Data Models/aggregate.yaml @@ -4,13 +4,15 @@ x-stoplight: type: object description: 'Aggregates are historic pre-computed counts and metrics of Events occurring in curb places, aggregated to the hour. All Aggregates can be calculated from the data defined in the **Session** object which is returned in the `metrics/sessions` endpoint of the CDS Metrics API.' properties: - curb_space_type: + curb_place_type: + type: string x-stoplight: id: gukvs97dshqqd enum: - area - zone - space + - object description: The type of curb place this aggregate applies to from the Curbs API. curb_place_id: type: string @@ -19,10 +21,12 @@ properties: format: uuid description: The id of the curb place identified in `curb_place_type`. metric_type: + type: string x-stoplight: id: i3l816hllui51 enum: - total_sessions + - total_events - turnover - average_dwell_time - occupancy_percent @@ -32,15 +36,24 @@ properties: x-stoplight: id: lh6zrzck6teja description: 'The date the event occured in ISO 8601 format, local timezone.' - example: '2023-04-31' + format: date + example: '2023-04-30' hour: - type: string + type: integer x-stoplight: id: a3vtd4y1ex7kj - example: '23' + example: 23 description: 'The hour of the day the event occured in ISO 8601 format, local timezone.' value: - type: string + type: number x-stoplight: id: 2r1yhfhxhsuym description: 'The results of the calculations for this metric from the [Methodology](https://github.com/openmobilityfoundation/curb-data-specification/tree/main/metrics#methodology). Note that "-1" means that the sensor/source was offline for the majority of the time.' + example: 100 +required: + - curb_place_type + - curb_place_id + - metric_type + - date + - hour + - value diff --git a/Shared Data Models/coordinates.yaml b/Shared Data Models/coordinates.yaml index 752a909..465f107 100644 --- a/Shared Data Models/coordinates.yaml +++ b/Shared Data Models/coordinates.yaml @@ -13,4 +13,8 @@ items: x-stoplight: id: zcetnhryqkc90 type: array + minItems: 2 + maxItems: 2 + items: + type: number description: Coordinates are defined as an array of collections/arrays where the nested arrays are 2 number values. These represent the latitude and longitude. diff --git a/Shared Data Models/curb_area.yaml b/Shared Data Models/curb_area.yaml index 7efc2b4..f9407d3 100644 --- a/Shared Data Models/curb_area.yaml +++ b/Shared Data Models/curb_area.yaml @@ -38,7 +38,15 @@ properties: items: type: string format: uuid - example: ' 0eaa505d-c9e1-49ad-9fac-3c745ba58676 ' + example: '0eaa505d-c9e1-49ad-9fac-3c745ba58676' + custom_attributes: + $ref: ./custom_attributes.yaml + description: Additional attributes (fields and data) to include in this endpoint. + external_references: + type: array + description: One or more references to external data feeds impacting this Curb Area. References external data that is relevant to this Area now. If the external reference is temporary, it should be added, then removed when no longer relevant. + items: + $ref: ./external_reference.yaml required: - curb_area_id - geometry diff --git a/Shared Data Models/curb_event.yaml b/Shared Data Models/curb_event.yaml index 2666046..34bff88 100644 --- a/Shared Data Models/curb_event.yaml +++ b/Shared Data Models/curb_event.yaml @@ -6,24 +6,25 @@ description: A Curb Event is a record of activity that happens within the geogra properties: event_id: type: string + format: uuid x-stoplight: id: xjwh3uor9vtj9 description: The globally unique identifier of the event that occurred. - format: uuid event_type: - $ref: ./event_purpose.yaml + $ref: ./event_type.yaml x-stoplight: id: e9o3ixjkgnvna - description: General curb usage purpose that the vehicle performed during the event. Required for sources capable of determining activity type for relevant event_types. + description: The event_type that happened for this event. event_purpose: $ref: ./event_purpose.yaml x-stoplight: id: 3iqfxzhwqegxd + description: General curb usage purpose that the vehicle performed during the event. Required for sources capable of determining activity type for relevant event_types. event_location: $ref: ./geoJSON_point.yaml x-stoplight: id: y19vh7p0lzd87 - description: 'The geo-location of where the event occurred, represented as a GeoJSON Point.' + description: The geographic point location where the event occurred. All efforts should be made to provide this field, even if slightly imprecise. But there may be times when a location is impossible or irrelevant. event_time: $ref: ./timestamp.yaml x-stoplight: @@ -33,33 +34,24 @@ properties: $ref: ./timestamp.yaml x-stoplight: id: 4v1u5gy1laa9l - description: Time at which the event became available for consumption from this API. + description: Time at which the event became available for consumption by this API. event_session_id: type: string + format: uuid x-stoplight: id: jj9z3s5o99fi3 - format: uuid - description: |- - May be provided to tie known connected park_start and park_end event types together by a unique session ID. - - If **not** confident of being able to determine a park_end event at some time after park_start is recorded (i.e., you cannot detect when a vehicle departs), then do **not** use session_id. + description: May be provided to tie known connected `park_start` and `park_end` event types together by a unique session ID. If not confident of being able to determine a `park_end` event at some time after `park_start` is recorded, do not use `event_session_id`. curb_zone_id: type: string + format: uuid x-stoplight: id: 68921cndpqjax - format: uuid - description: |- - Unique ID of the Curb Zone where the event occurred. - - Required for events that occurred at a known Curb Zone for **ALL** event_types. + description: Unique ID of the Curb Zone where the event occurred. Required for events that occurred in a known Curb Zone, if known and used, for ALL event_types. curb_area_ids: type: array x-stoplight: id: f49dygxi2plhh - description: |- - Unique IDs of the Curb Area where the event occurred. Since Curb Areas can overlap, an event may happen in more than one. - - Unique IDs of the Curb Area where the event occurred. Since Curb Areas can overlap, an event may happen in more than one. Required for events that occurred in a known Curb Area, if known and used, for these event_types: `enter_area`, `exit_area`, `park_start`, `park_end` + description: Unique IDs of the Curb Area where the event occurred. Since Curb Areas can overlap, an event may happen in more than one. Required for events that occurred in a known Curb Area, if known and used, for ALL event_types. items: x-stoplight: id: h4hgjz0397qtp @@ -67,37 +59,42 @@ properties: format: uuid curb_space_id: type: string + format: uuid x-stoplight: id: i1hz5ebvpvyp6 + description: Unique ID of the Curb Space where the event occurred. Required for events that occurred at a known Curb Space, if known and used, for ALL event_types. + curb_object_id: + type: string format: uuid - description: |- - Unique ID of the Curb Space where the event occurred. - - Required for events that occurred at a known Curb Space, if known and used, for these event_types: `park_start`, `park_end`, `enter_area`, `exit_area` + x-stoplight: + id: z2v5n8p1r6cqh + description: Unique ID of the Curb Object where the event occurred. Required for events that occurred at a known Curb Object, if known and used, for ALL event_types. data_source_type: $ref: ./data_source_type.yaml x-stoplight: id: tow3anlr8tr36 + description: General category of the source creating the event. data_source_operator_id: $ref: ./operator_id.yaml x-stoplight: id: b7peq7v42kjls + description: Unique identifier of the entity responsible for operating the event data source. IDs can identify the fleet operator sending a data feed, or the organization operating the sensor or other source. data_source_operator_name: type: string x-stoplight: id: swh4u6hrdy0ey - description: |- - Name of the provider responsible for operating the vehicle, device, or sensor at the time of the event. - - May be sent along with `data_source_operator_id` or on its own for small operators at the discretion of the city. + description: Name of the provider responsible for operating the vehicle, device, or sensor at the time of the event. May be sent along with `data_source_operator_id` or on its own for small operators at the discretion of the city. data_source_device_id: type: string + format: uuid x-stoplight: id: w91m0qzkjjacq - description: |- - Unique identifier of this event source, whether sensor, vehicle, camera, etc. Allows agencies to connect related Events as they are recorded by the same source. If coming from a provider, this is a generated UUID they use and not the same as the external `vehicle_id`. - - If this field is needed for your use cases, review our [Privacy Guidance](https://github.com/openmobilityfoundation/curb-data-specification/blob/main/README.md#data-privacy). + description: Unique identifier of this event source, whether sensor, vehicle, camera, or similar device. Allows agencies to connect related Events as they are recorded by the same source. If coming from a provider, this is a generated UUID they use and not the same as the external `vehicle_id`. + data_source_device_name: + type: string + x-stoplight: + id: r7c1m0f2l4pda + description: Unique name of this event source, whether sensor, vehicle, camera, or similar device. Must be provided if the device has a visible or shared identifier. data_source_manufacturer: type: string x-stoplight: @@ -112,60 +109,155 @@ properties: type: boolean x-stoplight: id: 3i9prwaz5klwz - description: 'If a sensor was used to capture this event, the commissioned status at the time that the event was reported. Indicates whether the sensor is currently in a state where it should be reporting data.' + description: If a sensor was used to capture this event, the commissioned status at the time that the event was reported. Indicates whether the sensor is currently in a state where it should be reporting data. sensor_status_is_online: type: boolean x-stoplight: id: 9ra1u95oix354 - description: 'If a sensor was used to capture this event, the online status at the time that the event was reported. Indicates whether the sensor is currently online and reporting data.' + description: If a sensor was used to capture this event, the online status at the time that the event was reported. Indicates whether the sensor is currently online and reporting data. vehicle_id: type: string x-stoplight: id: 3lyyz739s4ew1 - description: 'A vehicle identifier visible externally on the vehicle itself. If this field is needed for your use cases, review our [Privacy Guidance](https://github.com/openmobilityfoundation/curb-data-specification/blob/main/README.md#data-privacy).' + description: A vehicle identifier visible externally on the vehicle itself. If this field is needed for your use cases, review the CDS privacy guidance. vehicle_license_plate: type: string x-stoplight: id: cckfib2gi29uh - description: 'The consistently placed vehicle license plate, usable by ALPR systems, when required for curb use. This field is potentially sensitive (depending on local, state, and national laws) and a data privacy framework is recommended for collecting, retention, deletion, obfuscation, and security. If this field is needed for your use cases, review our [Privacy Guidance](https://github.com/openmobilityfoundation/curb-data-specification/blob/main/README.md#data-privacy).' + description: The consistently placed vehicle license plate, usable by ALPR systems, when required for curb use. This field may be sensitive depending on jurisdiction. + vehicle_license_plate_jurisdiction: + type: string + x-stoplight: + id: p1x9v0r6m2qsa + description: Jurisdiction or state in which the `vehicle_license_plate` is registered. + vehicle_license_plate_confidence: + type: integer + minimum: 1 + maximum: 100 + x-stoplight: + id: n6c4t7h2z8bpa + description: Value from 1 to 100 specifying the recognition confidence level for `vehicle_license_plate`. vehicle_permit_number: type: string x-stoplight: id: p9m8k37j17kcv - description: 'If applicable, the assigned permit number for this vehicle from the city agency.' + description: If applicable, the assigned permit number for this vehicle from the city agency. vehicle_length: - type: number + type: integer x-stoplight: id: zax8xvn9afq87 - description: |- - Approximate length of the vehicle that performed the event, measured in centimeters. - - Required for sources capable of determining vehicle length. + description: Approximate length of the vehicle that performed the event, measured in centimeters. Required for sources capable of determining vehicle length. + vehicle_type: + $ref: ./vehicle_type.yaml + x-stoplight: + id: d4w1o9q7e2lks + description: Type of the vehicle that performed the event. Required for sources capable of determining vehicle type. + vehicle_type_confidence: + type: integer + minimum: 1 + maximum: 100 + x-stoplight: + id: q3j8f0k1w5rns + description: Value from 1 to 100 specifying the recognition confidence level for `vehicle_type`. + vehicle_color: + type: string + x-stoplight: + id: t8m2c5d9y1vhr + description: Color of the vehicle that performed the event. + vehicle_color_confidence: + type: integer + minimum: 1 + maximum: 100 + x-stoplight: + id: b7n4p3k6s8ywd + description: Value from 1 to 100 specifying the recognition confidence level for `vehicle_color`. + vehicle_company_name: + type: string + x-stoplight: + id: v0m3q7n5x2lzc + description: Company or courier name of the vehicle that performed the event. + vehicle_company_name_confidence: + type: integer + minimum: 1 + maximum: 100 + x-stoplight: + id: h5c2r8j1p9dsa + description: Value from 1 to 100 specifying the recognition confidence level for `vehicle_company_name`. + vehicle_run_id: + type: string + x-stoplight: + id: k9d4s1f7m6qla + description: Run identifier from an external runs table containing information about the make, model, and/or year of the vehicle that performed the event. + vehicle_run_id_confidence: + type: integer + minimum: 1 + maximum: 100 + x-stoplight: + id: m1p8x3w6c4znt + description: Value from 1 to 100 specifying the recognition confidence level for `vehicle_run_id`. vehicle_propulsion_types: $ref: ./propulsion_type.yaml x-stoplight: id: yzh8z7wdjj72a + description: List of propulsion types used by the vehicle that performed the event. Required for sources capable of determining vehicle propulsion type. vehicle_blocked_lane_types: - $ref: ./lane_type.yaml + type: array x-stoplight: id: z3n62d0081u5j + description: Type(s) of lane blocked by the vehicle performing the event. If no lanes are blocked by the vehicle performing the event, the array should be empty. Required for sources capable of determining it for `park_start` events. + items: + $ref: ./lane_type.yaml curb_occupants: type: array x-stoplight: id: jysyhxqxkjnnz + description: Current occupants of the Curb Zone. If the source can determine linear location, the array should be ordered by the start of each occupant's linear reference. items: $ref: ./curb_occupant.yaml x-stoplight: id: bzse7o4oic8h4 actual_cost: type: integer + example: 100 x-stoplight: id: aifcs5wjnhqhu - description: 'If available from the source, the actual cost, in the currency defined in currency, paid by the curb user for this event. The currency type is sent in with the REST Endpoints JSON object. All costs should be given as integers in the currency''s smallest unit. As an example, to represent $1 USD, specify an amount of 100 (for 100 cents).' - example: 100 + description: If available from the source, the actual cost paid by the curb user for this event, in the currency's smallest unit. + enforcement: + $ref: ./enforcement.yaml + x-stoplight: + id: a8q2v6n1t5mzr + description: Enforcement information related to this Curb Event, relevant to the moment in time the event happens. Only used for enforcement related events such as `vehicle_detected`, `vehicle_violation_start`, `vehicle_violation_end`, and `citation_issued`. + payment_channel: + $ref: ./payment_channel.yaml + x-stoplight: + id: c6h1n4j8q5sza + description: If available from the source, the medium by which a user submitted payment. + payment_method: + $ref: ./payment_method.yaml + x-stoplight: + id: e4p9d2k7m1rxc + description: If available from the source, the method used to pay for this event. + payment_transaction_id: + type: string + x-stoplight: + id: u3k8m1x5q7vbd + description: The transaction ID of the payment if available from the source and different from the `event_id`. + custom_attributes: + $ref: ./custom_attributes.yaml + x-stoplight: + id: 4l3d9m8q2sk1v + description: Additional attributes (fields and data) to include in this endpoint. + external_references: + type: array + x-stoplight: + id: 7p2n4a8k3jw0c + description: One or more references to external data sources impacting this Curb Event. The external reference is relevant to the moment in time the event happens. + items: + $ref: ./external_reference.yaml required: - event_id - - event_location + - event_type - event_time + - event_publication_time - data_source_type - data_source_device_id diff --git a/Shared Data Models/curb_object.yaml b/Shared Data Models/curb_object.yaml new file mode 100644 index 0000000..d58d71d --- /dev/null +++ b/Shared Data Models/curb_object.yaml @@ -0,0 +1,140 @@ +title: Curb Object +x-stoplight: + id: 2b5f7d9n1c4qa +type: object +description: | + Defines individual assets located adjacent to, overlapping, within, or associated with a Curb Space or Curb Zone. Important notes about Curb Objects: + * Curb Objects can be located anywhere within, beside, or overlapping with Curb Zones, Spaces, or other Curb Objects + * Curb Objects must be associated with either a Curb Space or Curb Zone + * Curb Objects do not typically have Curb Policies linked directly to them (unless the object is directly aligned with a single Policy, using the optional `curb_policy_id` field). Associated Curb Policies can be found by looking at the related Curb Zone, either directly or through the Curb Space. + * Unlike Zones and similar to Spaces, Objects may be updated as needed, with a new `curb_object_id` being optionally assigned by the city +properties: + curb_object_id: + type: string + format: uuid + x-stoplight: + id: 6z1d4q8m2v7hy + description: The ID of the curb object. + geometry: + $ref: ./geoJSON_point.yaml + x-stoplight: + id: 1f8k3s9b6t2wr + description: The spatial location of this curb object location. This can represent the approximate center of the object, or the centroid location of the object, depending on its size and shape. + curb_zone_id: + type: string + format: uuid + x-stoplight: + id: 3v8m1q5d9n2kc + description: The ID of the Curb Zone this object is physically in or closest to. The geometry of the specified Curb Zone does not need to directly relate to the geometry of this object. Either a Zone or Space ID is required for an Object. + curb_space_id: + type: string + format: uuid + x-stoplight: + id: 5d1n8k3p7v2qx + description: The ID of the Curb Space this object is physically in or closest to. The geometry of the specified Curb Space does not need to directly relate to the geometry of this object. Either a Zone or Space ID is required for an Object. + curb_policy_id: + type: string + format: uuid + x-stoplight: + id: 2x7c4m9v1n6qd + description: ID of Policy object that is directly associated with this curb object. For example, `signage` or `paint` that relates to a single policy. + lane_type: + $ref: ./lane_type.yaml + x-stoplight: + id: 6q1v8n3c5m7px + description: The type of lane the curb object is primarily located in. + object_type: + type: string + x-stoplight: + id: 8c2m5n1p7v4qx + description: The category of the curb object. CDS includes well-known recommended values such as `signage`, `bus_stop`, `bike_rack`, `scooter_parking`, `ev_charging`, `ramp`, `meter`, `pay_station`, `paint`, `lighting`, `signal_cabinet`, `utility_box`, `fire_hydrant`, `surveillance_camera`, `barrier`, `bollard`, `street_trees`, `planter`, `drinking_fountain`, `toilet`, `bench`, `sculpture`, `art`, `fountain`, `solid_waste_bins`, `post_box`, `locker`, and `food_vendor`. The upstream list is intentionally not exhaustive, so additional local object types may be used when needed. + example: signage + name: + type: string + x-stoplight: + id: 4h9p2v6c1x8nd + description: A short name of this curb object for reference. + description: + type: string + x-stoplight: + id: 1c6m9q4v8n2px + description: A more detailed description of the object if needed. + owner: + type: string + x-stoplight: + id: 8m2q5v1n7c4pd + description: The name of the agency, department, or similar entity responsible for maintaining this object. + operator: + type: string + x-stoplight: + id: 4n8c1q7v5m2px + description: The name of the agency, department, or similar entity responsible for operating this object. + object_shape: + $ref: ./geoJSON_polygon.yaml + x-stoplight: + id: 7p1m4v8c2n6qd + description: A simplified geometric outline of this object. Recommended for objects that are an unusual shape and may affect curb activities. + object_line: + $ref: ./geoJSON_linestring.yaml + x-stoplight: + id: 3q6v1n8m5c2px + description: A simplified geometric line defining this object. Recommended for objects that may affect or help define curb activities, like `paint`. + linear_distance: + type: integer + x-stoplight: + id: 9n2c5m1q7v4pd + description: Parallel distance from the side of the object to the linear referencing start point of the curb, in centimeters. + perpendicular_distance: + type: integer + x-stoplight: + id: 2p7m4v8n1c6qx + description: Perpendicular distance from the front of the object to the curb edge start or end, in centimeters. This distance can be negative or positive, with the positive direction being from the curb toward the sidewalk. + max_length: + type: integer + x-stoplight: + id: 5m1q8v3n7c2pd + description: Maximum, bounding-box length of the object parallel to the curb, in centimeters. + max_depth: + type: integer + x-stoplight: + id: 1v6c9m4q8n2px + description: Maximum, bounding-box depth of the object perpendicular to the curb, in centimeters. + max_height: + type: integer + x-stoplight: + id: 8q3n5m1v7c2pd + description: Maximum, bounding-box height of the object from the sidewalk or street surface, in centimeters. + published_date: + $ref: ./timestamp.yaml + x-stoplight: + id: 7r3j6d1f8m2qp + description: The date/time that this curb object was first published in this data feed. + last_updated_date: + $ref: ./timestamp.yaml + x-stoplight: + id: 9k5n2b7t4c1sx + description: The date/time that the properties of this curb object were last updated. This helps consumers know that some fields may have changed. + custom_attributes: + $ref: ./custom_attributes.yaml + x-stoplight: + id: 4m7q1n8v3c2px + description: Additional attributes (fields and data) to include in this endpoint. + external_references: + type: array + x-stoplight: + id: 6n2c5m1q8v4pd + description: One or more references to external data feeds impacting this Curb Object. References external data that is relevant to this Object now. If the external reference is temporary, it should be added, then removed when no longer relevant. + items: + $ref: ./external_reference.yaml +required: + - curb_object_id + - geometry + - object_type + - name + - published_date + - last_updated_date +anyOf: + - required: + - curb_zone_id + - required: + - curb_space_id diff --git a/Shared Data Models/curb_policy.yaml b/Shared Data Models/curb_policy.yaml index ebd2998..cde92b3 100644 --- a/Shared Data Models/curb_policy.yaml +++ b/Shared Data Models/curb_policy.yaml @@ -13,6 +13,13 @@ properties: A `curb_policy_id` MUST NOT be reused. Once created, it must continue to refer to the identical policy forever. type: string + format: uuid + name: + type: string + description: User friendly name of policy. + description: + type: string + description: Detailed description of policy. published_date: $ref: ./timestamp.yaml description: |- @@ -21,7 +28,13 @@ properties: An integer representing a number of milliseconds since midnight, January 1st, 1970 UTC (the UNIX epoch) priority: type: integer - description: 'Specifies which other policies this one takes precedence over. If two Policies on the same Curb Zone have overlapping Time Spans and apply to the same user class, the one that applies at a given time is the one with the lowest priority.' + description: >- + Specifies which other policies this one takes precedence over. If two Policies + on the same Curb Zone have overlapping Time Spans and apply to the same user + class, the one that applies at a given time is the one with the lowest priority. + E.g., a priority of `1` takes precedence over a priority of `3`. Two Policies + that apply to the same Curb Zone with overlapping Time Spans MAY ONLY have the + same priority if the policies apply to disjoint User Classes or disjoint Activities. rules: type: array description: The rule(s) that this policy applies. @@ -42,6 +55,70 @@ properties: **Values are defined globally and are managed by the Open Mobility Foundation and operators may register [here](https://github.com/openmobilityfoundation/curb-data-specification/wiki/Adding-a-CDS-Data-Source-Operator-ID)** items: $ref: ./operator_id.yaml + policy_color: + type: object + description: > + A JSON object that defines the official colors used to represent this specific + policy, used in physical curb paint, digital and print maps, etc. + properties: + primary_color: + type: string + description: > + The 6 digit hexidecimal triplet value of the primary curb color, in standard + capitalized RRGGBB format, without a leading hash symbol ("#"). E.g. "839D8F", + "FF00FF". + primary_pattern_type: + type: string + description: > + One of `solid`, `long_dash`, `short_dash`, `dot`, `dot_dash`, `diagonal` + to define the type of pattern on the `primary_color`. + enum: + - solid + - long_dash + - short_dash + - dot + - dot_dash + - diagonal + primary_border_color: + type: string + description: The 6 digit hex value of the `primary_color` border color. + primary_border_pattern_type: + type: string + description: > + One of `solid`, `long_dash`, `short_dash`, `dot`, `dot_dash`, `diagonal` + to define the type of pattern on the `primary_border_color`. + enum: + - solid + - long_dash + - short_dash + - dot + - dot_dash + - diagonal + secondary_color: + type: string + description: The 6 digit hex value of the secondary curb color. + secondary_border_color: + type: string + description: The 6 digit hex value of the `secondary_color` border color. + secondary_border_pattern_type: + type: string + description: > + One of `solid`, `long_dash`, `short_dash`, `dot`, `dot_dash`, `diagonal` + to define the type of pattern on the `secondary_border_color`. + enum: + - solid + - long_dash + - short_dash + - dot + - dot_dash + - diagonal + required: + - primary_color + external_references: + type: array + description: External references that link this policy to other systems or specifications. + items: + $ref: ./external_reference.yaml required: - curb_policy_id - published_date diff --git a/Shared Data Models/curb_space.yaml b/Shared Data Models/curb_space.yaml index 65bdf5a..ac7ab3e 100644 --- a/Shared Data Models/curb_space.yaml +++ b/Shared Data Models/curb_space.yaml @@ -18,20 +18,26 @@ properties: x-stoplight: id: r3a5hu6diex3r description: |- - The date/time that this curb area was first published in this data feed. + The date/time that this curb space was first published in this data feed. An integer representing a number of milliseconds since midnight, January 1st, 1970 UTC (the UNIX epoch) last_updated_date: $ref: ./timestamp.yaml description: |- - The date/time that the properties of ths curb area were last updated. This helps consumers know that some fields may have changed. + The date/time that the properties of this curb space were last updated. This helps consumers know that some fields may have changed. An integer representing a number of milliseconds since midnight, January 1st, 1970 UTC (the UNIX epoch) curb_zone_id: description: The ID of the Curb Zone this space is within. The geometry of the specified Curb Zone MUST contain the geometry of this space. type: string format: uuid - example: ' 0eaa505d-c9e1-49ad-9fac-3c745ba58676 ' + example: '0eaa505d-c9e1-49ad-9fac-3c745ba58676' + curb_object_ids: + type: array + description: The ID(s) of the Curb Objects that this Curb Space is related to, in particular what Objects are in the Space's areas of influence. For example, a meter being used for two paid parking spaces, a locker for a commercial loading space, or a camera monitoring several spaces. If specified, the objects identified MUST be retrievable through a Curbs API Objects endpoint. + items: + type: string + format: uuid space_number: type: integer description: 'The sequence number of this space within its Zone. If specified, two spaces within the same Curb Zone MUST NOT share a space number, and space numbers SHOULD be consecutive positive integers starting at 1.' @@ -51,8 +57,23 @@ properties: If availability information is present, the most recent time that availability was computed for this space. An integer representing a number of milliseconds since midnight, January 1st, 1970 UTC (the UNIX epoch) + custom_attributes: + $ref: ./custom_attributes.yaml + description: Additional attributes (fields and data) to include in this endpoint. + external_references: + type: array + description: One or more references to external data feeds impacting this Curb Space. References external data that is relevant to this Space now. If the external reference is temporary, it should be added, then removed when no longer relevant. + items: + $ref: ./external_reference.yaml description: | Defines individual demarcated spaces within a Curb Zone. Important notes about Curb Spaces: * Curb Spaces may NOT overlap with other Curb Spaces - * Curb Spaces must be wholly contained within a single Curb Zone + * Curb Spaces must be wholly contained within or associated with a single Curb Zone * Unlike Zones, Spaces may be updated as needed, with a new `curb_space_id` being optionally assigned by the city +required: + - curb_space_id + - geometry + - published_date + - last_updated_date + - curb_zone_id + - length diff --git a/Shared Data Models/curb_status.yaml b/Shared Data Models/curb_status.yaml index 7658ead..340118a 100644 --- a/Shared Data Models/curb_status.yaml +++ b/Shared Data Models/curb_status.yaml @@ -2,9 +2,26 @@ title: Curb Status x-stoplight: id: hvscebeq5ob4d type: object +description: The Curb Status is the current status of sensors that are monitoring curb places. properties: - id: + data_source_device_id: type: string + format: uuid x-stoplight: id: adhs12kh3sx96 -description: The Curb Status is the current status of sensors that are monitoring curb places. + description: Unique identifier of this event source, whether sensor, vehicle, camera, or similar device. + data_source_type: + $ref: ./data_source_type.yaml + description: General category of the source creating the event. + data_source_operator_id: + $ref: ./operator_id.yaml + description: Unique identifier of the entity responsible for operating the event data source. Can be global from `data_source_operators.csv` or defined per city. + sensor_status_is_commissioned: + type: boolean + description: Indicates whether the sensor is currently in a state where it should be reporting data. + sensor_status_is_online: + type: boolean + description: Indicates whether the sensor is currently online and reporting data. +required: + - data_source_device_id + - data_source_type diff --git a/Shared Data Models/curb_zone.yaml b/Shared Data Models/curb_zone.yaml index 1d374ba..6c9227a 100644 --- a/Shared Data Models/curb_zone.yaml +++ b/Shared Data Models/curb_zone.yaml @@ -19,15 +19,21 @@ properties: curb_zone_id: type: string format: uuid - example: ' 0eaa505d-c9e1-49ad-9fac-3c745ba58676 ' + example: '0eaa505d-c9e1-49ad-9fac-3c745ba58676' geometry: - $ref: ./geoJSON_polygon.yaml - description: The spatial extent of this Curb Zone. + oneOf: + - $ref: ./geoJSON_polygon.yaml + - $ref: ./geoJSON_linestring.yaml + description: The spatial extent of this curb zone. A new `curb_zone_id` is required if this geometry changes. A two-dimensional polygon is preferred, but a LineString is acceptable. Include the `width` field if known. + description: + type: string + description: A more detailed description of the zone if needed. curb_policy_ids: type: array description: 'An array of IDs of Policy objects. Together, these define the regulations of this Curb Zone.' items: type: string + format: uuid published_date: $ref: ./timestamp.yaml prev_policies: @@ -52,6 +58,25 @@ properties: - end_date last_updated_date: $ref: ./timestamp.yaml + available: + type: boolean + description: If `true`, the curb zone is open for normal use. If `false`, the curb zone is closed and vehicles should look for alternative zones. Do not provide this field if the availability is unknown. + available_spaces: + type: integer + description: The number of curb spaces that are open for use within the Zone. Spaces could be a count of available marked or delineated spaces, or a count of the available CDS Curb Spaces. + jurisdiction_type: + type: string + enum: + - public + - private + - other + description: Describes the type of entity that has jurisdiction of this curb zone. Use `public` for curb zones maintained by a public sector agency, `private` for curb zones maintained by a private entity, or `other` for other cases. + owner_name: + type: string + description: Identifies the name of the owner of the curb zone. + address_number: + type: string + description: The address number, street number, civic number, or number range of the street that this Curb Zone is on. prev_curb_zone_ids: type: array description: An array of IDs of previous curb zone objects. They are listed in order with the most recent ones first. @@ -161,12 +186,27 @@ properties: items: type: string format: uuid + curb_object_ids: + type: array + description: |- + The ID(s) of the Curb Objects that this Curb Zone is related to, in particular what Objects are in the Zone's areas of influence. For example, a pay station being used for multiple paid parking zones, a locker for a commercial loading zone, or a camera monitoring several zones. If specified, the objects identified MUST be retrievable through a Curbs API Objects endpoint. + items: + type: string + format: uuid curb_space_ids: type: array description: The ID(s) of the Curb Spaces that this Curb Zone contains. items: type: string format: uuid + custom_attributes: + $ref: ./custom_attributes.yaml + description: Additional attributes (fields and data) to include in this endpoint. + external_references: + type: array + description: One or more references to external data feeds impacting this Curb Zone. The external reference should be relevant to this Zone now and may be updated without requiring a new `curb_zone_id`. + items: + $ref: ./external_reference.yaml required: - curb_zone_id - geometry diff --git a/Shared Data Models/custom_attributes.yaml b/Shared Data Models/custom_attributes.yaml new file mode 100644 index 0000000..f4f572f --- /dev/null +++ b/Shared Data Models/custom_attributes.yaml @@ -0,0 +1,11 @@ +title: Custom Attributes +type: object +description: > + Implementation-specific custom attributes for this object. + Custom attributes are one or more JSON name/value pairs, and the values must be + strings. +additionalProperties: + type: string +examples: + - color: "blue" + kiosk_id: "K-1234" diff --git a/Shared Data Models/enforcement.yaml b/Shared Data Models/enforcement.yaml new file mode 100644 index 0000000..3973cab --- /dev/null +++ b/Shared Data Models/enforcement.yaml @@ -0,0 +1,48 @@ +title: Enforcement +type: object +description: > + A specific set of enforcement details from a data feed or API that is relevant + to an enforcement Curb Event. +properties: + enforcement_id: + type: string + format: uuid + description: > + An identifier unique to the enforcement incident, generated the first time + an enforcement event is recorded and referenced in future related + enforcement events. + citation_id: + type: string + description: A unique id that represents a single citation. + is_warning: + type: boolean + description: Indicates whether the enforcement action is being processed as a warning. + action_taken: + type: string + description: Indicates how the violation was enforced. + enum: + - citation_registered + - citation_posted + - citation_served + - citation_emailed + citation_cost: + type: string + description: The total cost of all violations associated to this enforcement action. + violations: + type: array + description: > + One or more violation objects associated with this enforcement event. + items: + $ref: ./violation.yaml +required: + - enforcement_id +examples: + - enforcement_id: 123e4567-e89b-12d3-a456-426614174000 + citation_id: C-2026-0001 + is_warning: false + action_taken: citation_posted + citation_cost: "6500" + violations: + - violation_code: NO_PARKING + violation_name: No parking in loading zone + violation_cost: "6500" diff --git a/Shared Data Models/event_purpose.yaml b/Shared Data Models/event_purpose.yaml index befe645..7839e10 100644 --- a/Shared Data Models/event_purpose.yaml +++ b/Shared Data Models/event_purpose.yaml @@ -2,38 +2,11 @@ title: Event Purpose x-stoplight: id: 6uj3ohchgx8f9 type: string -enum: - - construction - - delivery - - emergency_use - - parking - - passenger_transport - - special_events - - waste_management - - device_maintenance - - autonomous - - ems - - fire - - food_delivery - - parcel_delivery - - police - - public_transit - - ride_hail - - road_maintenance - - service_vehicles - - taxi - - utility_work - - vehicle_charging - - vehicle_parking - - vending - - unspecified description: |- General event purpose that the vehicle performed during its event, discernible by observation, sensors, or self-reported in company data feeds. New event purposes MAY be generated to reflect local curb uses, but when possible, the following well-known recommended values should be used. It may not always be knowable, but where it is possible this information should be conveyed. - If multiple purposes apply, then use the more descriptive/specific value. For a description of each value in the enumeration, the OMF's documentation can be found [here](https://github.com/openmobilityfoundation/curb-data-specification/tree/main/events#event-purpose). + If multiple purposes apply, then use the more descriptive or specific value. - |Value|Description| - |--------------|-----| - | value | description | + Well-known recommended values include `construction`, `delivery`, `emergency_use`, `parking`, `passenger_transport`, `special_events`, `waste_management`, `device_maintenance`, `autonomous`, `ems`, `fire`, `food_delivery`, `parcel_delivery`, `police`, `public_transit`, `ride_hail`, `road_maintenance`, `service_vehicles`, `taxi`, `utility_work`, `vehicle_charging`, `vehicle_parking`, `vending`, and `unspecified`. diff --git a/Shared Data Models/event_type.yaml b/Shared Data Models/event_type.yaml index 4c241aa..a538cfa 100644 --- a/Shared Data Models/event_type.yaml +++ b/Shared Data Models/event_type.yaml @@ -11,4 +11,8 @@ enum: - scheduled_report - enter_area - exit_area + - vehicle_detected + - vehicle_violation_start + - vehicle_violation_end + - citation_issued description: A description of what event occurred. diff --git a/Shared Data Models/external_reference.yaml b/Shared Data Models/external_reference.yaml new file mode 100644 index 0000000..fcffe23 --- /dev/null +++ b/Shared Data Models/external_reference.yaml @@ -0,0 +1,44 @@ +title: External Reference +type: object +description: > + A reusable structure for linking CDS objects to an external data source that + impacts or provides information about a CDS object. +properties: + reference_url: + type: string + format: uri + description: > + A web-accessible identifier URL for the source of the publicly or privately + accessible data feed, document, website, or similar resource. This must be + a full HTTPS URL pointing to a location that contains more information. + name: + type: string + description: > + Name of the data source for reference, such as WZDx, CWZ, MDS, GBFS, GTFS, + or CDS. + public: + type: boolean + description: > + Indicates whether the reference URL can be viewed without authentication, + authorization, or an API key. + identifier_name: + type: string + description: > + The name of the data field or object referenced by the unique ids, such as + id, trip_id, vehicle_id, or RoadEventFeature. + ids: + type: array + description: > + One or more identifiers from the referenced URL that impact the use of or + relationship to part of CDS. + items: + type: string +required: + - reference_url +examples: + - reference_url: https://example.com/wzdx/road-events + name: WZDx + public: true + identifier_name: RoadEventFeature + ids: + - road_event_feature_1234 diff --git a/Shared Data Models/geoJSON_linestring.yaml b/Shared Data Models/geoJSON_linestring.yaml new file mode 100644 index 0000000..07539ff --- /dev/null +++ b/Shared Data Models/geoJSON_linestring.yaml @@ -0,0 +1,29 @@ +title: GeoJSON LineString +type: object +description: > + The spatial extent of this location represented as a GeoJSON geometry of type + "LineString" as defined in RFC 7946 3.1.4. +properties: + type: + type: string + description: A GeoJSON type. + example: LineString + coordinates: + type: array + description: > + An array of positions for this geometry. Each position is an array of two + numbers representing longitude and latitude. + items: + type: array + items: + type: number +required: + - type + - coordinates +examples: + - type: LineString + coordinates: + - [-73.982105, 40.767932] + - [-73.973694, 40.764551] + - [-73.949318, 40.796918] + diff --git a/Shared Data Models/geoJSON_point.yaml b/Shared Data Models/geoJSON_point.yaml index 38c2c1a..762f36e 100644 --- a/Shared Data Models/geoJSON_point.yaml +++ b/Shared Data Models/geoJSON_point.yaml @@ -24,7 +24,7 @@ properties: x-stoplight: id: qskkkudk4ofyb type: number - example: '-73.982105,40.767932' + example: -73.982105 required: - type - coordinates diff --git a/Shared Data Models/lane_type.yaml b/Shared Data Models/lane_type.yaml index 0d0b164..262c59c 100644 --- a/Shared Data Models/lane_type.yaml +++ b/Shared Data Models/lane_type.yaml @@ -5,6 +5,7 @@ type: string enum: - travel_lane - turn_lane + - center_turn_lane - bike_lane - bus_lane - parking @@ -17,8 +18,9 @@ description: |- |Value|Description| |--------------|-----| - | human | A standard vehicle travel lane. | + | travel_lane | A standard vehicle travel lane. | | turn_lane | A dedicated turn lane. | + | center_turn_lane | A center lane available for turns in both directions. Sometimes used for courier parking for loading activity. | | bike_lane | A lane dedicated for usage by cyclists. | | bus_lane | A lane dedicated for usage by buses. | | parking | A lane used for parking, not allowed for travel. | diff --git a/Shared Data Models/payment_channel.yaml b/Shared Data Models/payment_channel.yaml new file mode 100644 index 0000000..e9894e0 --- /dev/null +++ b/Shared Data Models/payment_channel.yaml @@ -0,0 +1,14 @@ +title: Payment Channel +type: string +description: > + The medium or platform used to pay for a curb event. +enum: + - meter + - mobile_app + - sms + - telephone + - website + - other +examples: + - meter + diff --git a/Shared Data Models/payment_method.yaml b/Shared Data Models/payment_method.yaml new file mode 100644 index 0000000..7b7d72e --- /dev/null +++ b/Shared Data Models/payment_method.yaml @@ -0,0 +1,19 @@ +title: Payment Method +type: string +description: > + The method used to pay for a curb event. +enum: + - cash + - credit_card + - digital_wallet + - smart_card + - membership_card + - billing + - permit + - voucher + - courtesy + - test + - other +examples: + - credit_card + diff --git a/Shared Data Models/propulsion_type.yaml b/Shared Data Models/propulsion_type.yaml index a144bc8..3d55a64 100644 --- a/Shared Data Models/propulsion_type.yaml +++ b/Shared Data Models/propulsion_type.yaml @@ -3,14 +3,31 @@ x-stoplight: id: exicw88mt3m4k type: array description: |- - The method of propulsion for a vehicle. Vehicles that may have one or more values from the enumeration can be represented as an array with multiple types. + Propulsion type `vehicle_propulsion_types` of the vehicle, similar to + `propulsion_type` in MDS. For this CDS release the list will be developed + independently here to accommodate CDS and MDS use cases, while still aligning + to the MDS design principles. In the next major MDS 2.0 release and next CDS + release, alignment between CDS and MDS propulsion types can occur. |Value|Description| |--------------|-----| - | human | Pedal or foot propulsion | - | electric_assist | Provides power only alongside human propulsion | - | electric | Contains throttle mode with a battery-powered motor | - | combustion | Contains throttle mode with a gas engine-powered motor | + | human | Pedal or foot propulsion | + | electric_assist | Provides electric motor assist only in combination with human propulsion - no throttle mode | + | electric | Powered by battery-powered electric motor with throttle mode | + | combustion | Powered by gasoline combustion engine | + | combustion_diesel | Powered by diesel combustion engine | + | hybrid | Powered by combined combustion engine and battery-powered motor | + | hydrogen_fuel_cell | Powered by hydrogen fuel cell powered electric motor | + | plug_in_hybrid | Powered by combined combustion engine and battery-powered motor with plug-in charging | + + A vehicle may have one or more values from the `vehicle_propulsion_types`, + depending on the number of modes of operation. For example, a scooter that can + be powered by foot or by electric motor would have the + `vehicle_propulsion_types` represented by the array `["human", "electric"]`. + A bicycle with pedal-assist would have the `vehicle_propulsion_types` + represented by the array `["human", "electric_assist"]` if it can also be + operated as a traditional bicycle. A hybrid vehicle may use + `["combustion", "electric"]`. items: x-stoplight: id: 1vps8ofx4ythw @@ -19,3 +36,7 @@ items: - electric_assist - electric - combustion + - combustion_diesel + - hybrid + - hydrogen_fuel_cell + - plug_in_hybrid diff --git a/Shared Data Models/rules.yaml b/Shared Data Models/rules.yaml index 924c9d0..abbea92 100644 --- a/Shared Data Models/rules.yaml +++ b/Shared Data Models/rules.yaml @@ -4,6 +4,12 @@ x-stoplight: type: object description: 'A rule defines who is allowed to do what, and for how long, on a curb, per the policy.' properties: + name: + type: string + description: User friendly name of rule. + description: + type: string + description: Detailed description of rule. activity: type: string enum: @@ -31,39 +37,33 @@ properties: description: The Unit of Time associated with the no_return value. user_classes: type: array - description: A user class represents any class of vehicles that is regulated by a city with respect to curb space. + description: > + User classes describe which vehicles, vehicle properties, or permit types + a rule applies to. All values in the array must match for the rule to apply. + Locally generated user classes are allowed. Well-known recommended values + include bicycle, bus, cargo_bicycle, car, moped, motorcycle, scooter, + shuttle, truck, van, accessible, autonomous, combustion, electric, + electric_assist, and human. + items: + type: string + user_classes_except: + type: array + description: > + If specified, the rule applies only to users who do not match any of the + listed user classes. Locally generated user classes are allowed. + items: + type: string + purposes: + type: array + description: > + The permitted purposes associated with this rule. If specified, the rule + applies only when one of the listed purposes matches. Locally generated + purpose values are allowed. Well-known recommended values include + construction, delivery, disabled_parking_permit, emergency_use, freight, + parking, permit, rideshare, carshare, school, service_vehicles, + special_events, taxi, utilities, valet, vending, and waste_management. items: type: string - enum: - - bicycle - - bus - - cargo_bicycle - - car - - moped - - motorcycle - - scooter - - truck - - van - - handicap-accessible - - human - - electric_assist - - electric - - combustion - - autonomous - - construction - - delivery - - emergency_use - - freight - - parking - - permit - - rideshare - - school - - service_vehicles - - special_events - - taxi - - utilities - - vending - - waste_management rate: type: array description: The cost of using this Curb Zone when this regulation applies. @@ -95,6 +95,9 @@ properties: end_duration: type: integer description: The number of rate_units after which the rate stops applying. + maximum_fee: + type: integer + description: The maximum amount in cents a user of the curb can pay for a particular parking event. required: - rate - rate_unit diff --git a/Shared Data Models/session.yaml b/Shared Data Models/session.yaml index 2403638..9b0092b 100644 --- a/Shared Data Models/session.yaml +++ b/Shared Data Models/session.yaml @@ -5,6 +5,7 @@ type: object description: 'Sessions are a historic subset of curb events, with some rows combined, some columns removed for clarity and privacy, and for only some curb event types. Sessions are meant to provide a granular view of parking and area sessions happening around the curb places, so consumers can do their own analysis.' properties: session_type: + type: string x-stoplight: id: 49itgyeou9waj description: The type of session that happened for this event. @@ -15,17 +16,20 @@ properties: type: string x-stoplight: id: 8lcen78qfos5h - description: Used to tie two events together. Will be the `event_session_id` from two events that are related. + description: If known and recorded to tie two Events together, include the `event_session_id` from the Curb Event. + format: uuid event_id_start: type: string x-stoplight: id: fvcmaudenb031 description: The globally unique identifier of the start/enter event that occurred. + format: uuid event_id_end: type: string x-stoplight: id: wlxhekqn5l8bh description: The globally unique identifier of the end/exit event that occurred. + format: uuid event_location_start_latitude: $ref: ./latitude.yaml x-stoplight: @@ -50,7 +54,7 @@ properties: $ref: ./timestamp.yaml x-stoplight: id: 8pxac87n00v0s - description: Timestamp (date/time) at which the event started with the `park_start` or `enter_area`` event types. + description: Timestamp (date/time) at which the event started with the `park_start` or `enter_area` event types. event_time_end: $ref: ./timestamp.yaml x-stoplight: @@ -78,6 +82,12 @@ properties: id: a1ikxiabeqv97 description: 'Unique ID of the Curb Space where the event occurred. Conditionally required for events that occurred at a known Curb Space for these event_types: park_start, park_end, enter_area, exit_area' format: uuid + curb_object_id: + type: string + x-stoplight: + id: 0f6kq2w1z9hmc + description: 'Unique ID of the Curb Object where the event occurred. Conditionally required for events that occurred at a known Curb Object for these event_types: `park_start`, `park_end`, `enter_area`, `exit_area`.' + format: uuid vehicle_length: type: integer x-stoplight: diff --git a/Shared Data Models/time_spans.yaml b/Shared Data Models/time_spans.yaml index c785e75..3c60845 100644 --- a/Shared Data Models/time_spans.yaml +++ b/Shared Data Models/time_spans.yaml @@ -19,16 +19,18 @@ properties: An integer representing a number of milliseconds since midnight, January 1st, 1970 UTC (the UNIX epoch) days_of_week: - type: string - enum: - - sun - - mon - - tue - - wed - - thu - - fri - - sat + type: array description: An array of days of the week when this time span applies. + items: + type: string + enum: + - sun + - mon + - tue + - wed + - thu + - fri + - sat days_of_month: type: array description: An array of days of the month when this time span applies. @@ -36,6 +38,16 @@ properties: type: integer minimum: 1 maximum: 31 + weeks_of_month: + type: array + description: > + An array of weeks of the month when this time span applies, specified as + integers (1-5), to represent ordinal weeks. E.g. "2" would be the 2nd + week of the month. + items: + type: integer + minimum: 1 + maximum: 5 months: type: array description: 'If specified, this time span applies only during these months (1=January, 12=December).' @@ -51,12 +63,13 @@ properties: description: 'The local time that this time span stops applying, as 24-hour "HH:MM".' designated_period: type: string - enum: - - snow emergency - - holidays - - school days - - game days - description: 'A string representing an arbitrarily-named, externally-defined period of time.' + description: > + A string representing an arbitrarily-named, externally-defined period of + time. Any values MAY be specified but the following known values SHOULD be + used when possible. designated_period_except: type: boolean - description: 'If specified and true, this time span applies at all times not matching the named designated period.' \ No newline at end of file + description: > + If specified and true, all fields in this Time Span are describing a + period in which the associated rule does not apply. This field takes + precedence over designated_period when present. diff --git a/Shared Data Models/timestamp.yaml b/Shared Data Models/timestamp.yaml index d311af6..b878688 100644 --- a/Shared Data Models/timestamp.yaml +++ b/Shared Data Models/timestamp.yaml @@ -1,6 +1,6 @@ title: Timestamp x-stoplight: id: wts331n59lxqu -type: number +type: integer description: 'An integer representing a number of milliseconds since midnight, January 1st, 1970 UTC (the UNIX epoch)' example: 1643130000000 diff --git a/Shared Data Models/vehicle_type.yaml b/Shared Data Models/vehicle_type.yaml index 3ee9788..76f7202 100644 --- a/Shared Data Models/vehicle_type.yaml +++ b/Shared Data Models/vehicle_type.yaml @@ -3,10 +3,14 @@ x-stoplight: id: 1525213d884c3 type: string enum: - - bicyle + - bicycle + - bus - cargo_bicycle - car + - delivery_robot - scooter + - scooter_standing + - scooter_seated - moped - motorcycle - truck diff --git a/Shared Data Models/violation.yaml b/Shared Data Models/violation.yaml new file mode 100644 index 0000000..aa54dc0 --- /dev/null +++ b/Shared Data Models/violation.yaml @@ -0,0 +1,23 @@ +title: Violation +type: object +description: > + A violation associated with an enforcement action that can occur as a Curb Event. +properties: + violation_code: + type: string + description: > + The unique code created by the municipality, city, county, state, federal, + or enforcement agency to identify the type of rule being enforced. + violation_name: + type: string + description: > + The city/municipal, county, state, provincial, or federal code that was + violated. + violation_cost: + type: string + description: The original cost associated with the violation. +examples: + - violation_code: NO_PARKING + violation_name: No parking in loading zone + violation_cost: "6500" + diff --git a/V1.1_IMPLEMENTATION_PLAN.md b/V1.1_IMPLEMENTATION_PLAN.md new file mode 100644 index 0000000..2ce56fb --- /dev/null +++ b/V1.1_IMPLEMENTATION_PLAN.md @@ -0,0 +1,229 @@ +# CDS OpenAPI v1.1 – Implementation Plan + +## Goal + +Bring the local `draft-v1.1` branch of `cds-openapi` into parity with the +upstream `main` branch of +[`openmobilityfoundation/curb-data-specification`](https://github.com/openmobilityfoundation/curb-data-specification), +using the upstream specification as of April 7, 2026 as the source of truth. + +Read `AGENTS.MD` for workflow rules and upstream-reference guidance before +editing the spec. + +--- + +## Highlights / Outstanding Decisions + +- `custom_attributes_dictionary` vs `custom_attribute_dictionary` + + - `general-information.md` file uses `custom_attributes_dictionary` - https://github.com/openmobilityfoundation/curb-data-specification/blob/release-1.1.0/general-information.md?plain=1 + + - `data-types.md` file uses `custom_attribute_dictionary` - https://github.com/openmobilityfoundation/curb-data-specification/blob/release-1.1.0/data-types.md?plain=1#L17 + + - **Going with `custom_attributes_dictionary` as that is what we have primarily documented.** + +--- + +## Active Path Forward + +### Phase 1 – Foundation And Early Alignment + +- ~~Bump the API specs to v1.1 and clean up baseline metadata and lint issues.~~ +- ~~Fix the pre-existing schema defects in `curb_event.yaml`, + `vehicle_type.yaml`, `time_spans.yaml`, `coordinates.yaml`, and + `APIs/Curbs API.yaml`.~~ +- ~~Align `external_reference.yaml` with the upstream CDS data-types table.~~ +- ~~Add the foundational shared schemas: + `custom_attributes.yaml`, `geoJSON_linestring.yaml`, + `payment_channel.yaml`, `payment_method.yaml`, `enforcement.yaml`, and + `violation.yaml`.~~ +- ~~Update the foundational shared value lists and policy fields used across the spec: + `event_type.yaml`, `vehicle_type.yaml`, `propulsion_type.yaml`, + `rules.yaml`, `curb_policy.yaml`, and `time_spans.yaml`.~~ + +--- + +### Phase 2 – Shared Model Parity + +#### ~~2A. `curb_zone.yaml`~~ + +- **Files:** `Shared Data Models/curb_zone.yaml` +- **Done when:** + - `geometry` supports both Polygon and LineString in the same field + - no separate `geometry_line` field is introduced + - missing upstream fields are added: + `description`, `jurisdiction_type`, `owner_name`, `address_number`, + `available`, `available_spaces`, `custom_attributes`, `curb_object_ids`, + `external_references` + - UUID typing is corrected where needed for policy ID arrays + +#### ~~2B. `curb_area.yaml`~~ + +- **Files:** `Shared Data Models/curb_area.yaml` +- **Done when:** + - `custom_attributes` is added + - `external_references` is added + - the required fields still match the upstream table + +#### ~~2C. `curb_space.yaml`~~ + +- **Files:** `Shared Data Models/curb_space.yaml` +- **Done when:** + - `curb_object_ids`, `custom_attributes`, and `external_references` are added + - the required fields match upstream: + `curb_space_id`, `geometry`, `published_date`, `last_updated_date`, + `curb_zone_id`, `length` + - `curb_object_ids` is described as conditionally required only in prose, not + made globally required in schema + +#### ~~2D. `curb_object.yaml`~~ + +- **Files:** `Shared Data Models/curb_object.yaml` +- **Done when:** + - a new `curb_object.yaml` model exists + - required fields match upstream: + `curb_object_id`, `geometry`, `object_type`, `name`, `published_date`, + `last_updated_date` + - conditional relationship requirement between `curb_zone_id` and + `curb_space_id` is documented + - optional fields from the current upstream table are represented, including + `lane_type`, shape or line geometry, dimensions, `custom_attributes`, and + `external_references` + +#### ~~2E. `curb_event.yaml`~~ + +- **Files:** `Shared Data Models/curb_event.yaml` +- **Done when:** + - ~~`external_references` and `custom_attributes` are already present~~ + - missing upstream fields are added: + `curb_object_id`, `data_source_device_name`, `payment_channel`, + `payment_method`, `payment_transaction_id`, `enforcement`, `vehicle_type`, + `vehicle_license_plate_jurisdiction`, `vehicle_license_plate_confidence`, + `vehicle_type_confidence`, `vehicle_color`, `vehicle_color_confidence`, + `vehicle_company_name`, `vehicle_company_name_confidence`, + `vehicle_run_id`, `vehicle_run_id_confidence` + - confidence fields are modeled as integers from `1` to `100` + - `event_publication_time` is required + - `event_location` is no longer globally required + - UUID typing and field descriptions match the upstream table + +#### ~~2F. `session.yaml`~~ + +- **Files:** `Shared Data Models/session.yaml` +- **Done when:** + - `curb_object_id` is added + - the local-only `custom_attributes` field is removed or explicitly reverted + - field types and descriptions match the current Metrics session columns + +#### ~~2G. `aggregate.yaml`~~ + +- **Files:** `Shared Data Models/aggregate.yaml` +- **Done when:** + - `curb_space_type` is renamed to `curb_place_type` + - `curb_place_type` includes `object` + - `metric_type` includes `total_events` + - `total_enforcement_events` is not introduced + - scalar types match upstream: + `date` is `date`, `hour` is `integer`, `value` is `number` + - the local-only `custom_attributes` field is removed or explicitly reverted + +--- + +### Phase 3 – API Parity + +#### ~~3A. `Curbs API.yaml`~~ + +- **Files:** `APIs/Curbs API.yaml` +- **Done when:** + - an `objects` tag is added + - `GET /curbs/objects` is added with only `time`, `zone`, and `space` + - `GET /curbs/objects/{id}` is added with optional `time` + - both object endpoints include `501 Not Implemented` + - list responses use the same `data.` wrapper pattern consistently + +#### ~~3B. `Events API.yaml` GET parity~~ + +- **Files:** `APIs/Events API.yaml` +- **Done when:** + - `event_time` is added to `GET /events/events` + - `curb_object_id` is added to `GET /events/events` + - `curb_object_id` is added to `GET /events/status` + +#### ~~3C. `Events API.yaml` POST parity~~ + +- **Files:** `APIs/Events API.yaml` +- **Done when:** + - `POST /events/event` is added at the correct singular path + - deduplication guidance by `event_id` is documented + - response coverage matches upstream: + `200`, `201`, `400`, `401`, `404`, `406`, `409`, `500`, `501` + +#### ~~3D. `Events API.yaml` auth and error guidance~~ + +- **Files:** `APIs/Events API.yaml` +- **Done when:** + - GET endpoints are marked as authorization recommended + - POST `/events/event` is marked as authorization required + - event ordering guidance is aligned with `general-information.md#event-times` + - error and bulk-response descriptions align with upstream general information + +#### ~~3E. `Metrics API.yaml` contract parity~~ + +- **Files:** `APIs/Metrics API.yaml` +- **Done when:** + - Metrics is represented as a CSV API, not a JSON wrapper API + - the media type reflects + `application/vnd.cds+csv;version=1.1` + - `curb_place_type` includes `object` + - `metric_type` includes `total_events` + - `start_time` is documented as inclusive + - `end_time` is documented as exclusive + +#### ~~3F. `Metrics API.yaml` descriptive parity~~ + +- **Files:** `APIs/Metrics API.yaml` +- **Done when:** + - recommended authorization guidance is added + - representative-sample-data and update-frequency guidance are reflected where useful + - `501 Not Implemented` wording is consistent + - any row examples or schema surrogates match the updated shared models + +--- + +### Phase 4 – Validation And Cleanup + +#### 4A. JSON wrapper and auth cleanup + +- **Files:** `APIs/Curbs API.yaml`, `APIs/Events API.yaml` +- **Done when:** + - JSON endpoint wrappers match `general-information.md#rest-endpoints` + - the conditional `custom_attributes_dictionary` field is handled consistently + - optional endpoints consistently document `501 Not Implemented` + - bearer-auth documentation is aligned where auth is required or recommended + +#### 4B. `toc.json` + +- **Files:** `toc.json` +- **Done when:** + - ~~entries exist for `Custom Attributes`, `External Reference`, + `GeoJSON LineString`, `Enforcement`, `Violation`, `Payment Channel`, and + `Payment Method`~~ + - `Curb Object` is added under `CDS Models` + +#### 4C. Lint and final upstream review + +- **Files:** full repo +- **Done when:** + - `.spectral.mjs` passes + - all `$ref` paths are valid + - every new or changed field has a description + - required arrays match upstream tables + - a final field-by-field re-check against the source-of-truth docs is complete + - known ambiguities are either resolved locally or explicitly documented + +--- + +## Definition Of Done + +The `draft-v1.1` branch is a current representation of the CDS API +specification as it appears on the upstream `main` branch. diff --git a/original_CDS APIs.yaml b/original_CDS APIs.yaml deleted file mode 100644 index 5f8c5d4..0000000 --- a/original_CDS APIs.yaml +++ /dev/null @@ -1,1898 +0,0 @@ -openapi: 3.1.0 -x-stoplight: - id: 4wvvx7c8j5ymv -tags: - - name: Curbs API - description: The Curbs API is a REST API allowing cities to specify areas of interest along the curb along with the rules for using them - - name: Events API - description: 'The Events API is a REST API allowing real-time and historic events at the curb to be sent to cities, and the ability to check on the status of any sensors.' - - name: Metrics API - description: The Metrics API is a REST API allowing historic metrics calculations based on Event activity that happened at defined Curb places -info: - title: Curb Data Specification - version: 1.0.0 - summary: 'CDS is a data specification to help cities manage their curb zone programs and surrounding areas, and measure the utilization and impact.' - description: 'The Curb Data Specification (CDS), a project of the Open Mobility Foundation (OMF), is a data standard and set of Application Programming Interfaces (APIs) that helps cities manage and companies use dynamic curb zones that optimize loading activities of people and goods, and measure the impact of these programs.' - contact: - url: 'https://github.com/openmobilityfoundation/curb-data-specification/' - name: Open Mobility Foundation - email: info@openmobilityfoundation.org - license: - name: Creative Commons Attribution 4.0 International Public License - url: 'http://www.apache.org/licenses/LICENSE-2.0.htmlhttps://github.com/openmobilityfoundation/curb-data-specification/blob/0706316a7bfb0d6b5104c75608d8f66cb8101fe7/LICENCE' -servers: [] -paths: - /curbs/zones: - get: - summary: Get Curb Zones - responses: - '200': - description: Zones Found - content: - application/json: - schema: - type: object - properties: - version: - $ref: '#/components/schemas/rest-response-version' - time_zone: - $ref: '#/components/schemas/rest-response-time_zone' - last_updated: - $ref: '#/components/schemas/rest-response-last_updated' - currency: - $ref: '#/components/schemas/rest-response-currency' - author: - $ref: '#/components/schemas/rest-response-author' - license_url: - $ref: '#/components/schemas/rest-response-license_url' - data: - type: array - items: - type: object - properties: - zones: - type: array - items: - $ref: '#/components/schemas/curb_zone' - '400': - description: BAD_REQUEST - '401': - description: UNAUTHORIZED - '403': - description: FORBIDDEN - '500': - description: SERVER_ERROR - '503': - description: SERVICE_UNAVAILABLE - operationId: get-curbs-zones - description: 'This required endpoint must be implemented by every Curbs API server. If attaching policies to curb zones, the Query Curb Policies endpoint is also required.' - parameters: - - schema: - $ref: '#/components/schemas/uuid' - in: query - name: area - description: 'The ID of a Curb Area. If specified, only return Curb Zones contained within this area.' - - $ref: '#/components/parameters/min_lat' - - $ref: '#/components/parameters/min_lng' - - $ref: '#/components/parameters/max_lat' - - $ref: '#/components/parameters/max_lng' - - $ref: '#/components/parameters/lat' - - $ref: '#/components/parameters/lng' - - $ref: '#/components/parameters/radius' - tags: - - Curbs API - x-stoplight: - id: rf9d12orekm1h - /curbs/areas: - get: - summary: Get Curb Areas - responses: - '200': - description: Areas Found - content: - application/json: - schema: - type: object - properties: - version: - $ref: '#/components/schemas/rest-response-version' - time_zone: - $ref: '#/components/schemas/rest-response-time_zone' - last_updated: - $ref: '#/components/schemas/rest-response-last_updated' - currency: - $ref: '#/components/schemas/rest-response-currency' - author: - $ref: '#/components/schemas/rest-response-author' - license_url: - $ref: '#/components/schemas/rest-response-license_url' - data: - type: array - items: - type: object - properties: - areas: - type: array - items: - $ref: '#/components/schemas/curb_area' - '400': - description: BAD_REQUEST - '401': - description: UNAUTHORIZED - '403': - description: FORBIDDEN - '500': - description: SERVER_ERROR - '501': - description: NOT_IMPLEMENTED - '503': - description: SERVICE_UNAVAILABLE - operationId: get-curbs-areas - description: 'Optional endpoint. If not implemented, the server should reply with 501 Not Implemented.' - parameters: - - $ref: '#/components/parameters/min_lat' - - $ref: '#/components/parameters/min_lng' - - $ref: '#/components/parameters/max_lat' - - $ref: '#/components/parameters/max_lng' - - $ref: '#/components/parameters/lat' - - $ref: '#/components/parameters/lng' - - $ref: '#/components/parameters/radius' - tags: - - Curbs API - security: [] - x-stoplight: - id: 2rmkdtzdroapa - /curbs/spaces: - get: - summary: Get Curb Spaces - responses: - '200': - description: Spaces Found - content: - application/json: - schema: - type: object - properties: - version: - $ref: '#/components/schemas/rest-response-version' - time_zone: - $ref: '#/components/schemas/rest-response-time_zone' - last_updated: - $ref: '#/components/schemas/rest-response-last_updated' - currency: - $ref: '#/components/schemas/rest-response-currency' - author: - $ref: '#/components/schemas/rest-response-author' - license_url: - $ref: '#/components/schemas/rest-response-license_url' - data: - type: array - items: - type: object - properties: - spaces: - type: array - items: - $ref: '#/components/schemas/curb_space' - '400': - description: BAD_REQUEST - '401': - description: UNAUTHORIZED - '403': - description: FORBIDDEN - '500': - description: SERVER_ERROR - '501': - description: NOT_IMPLEMENTED - '503': - description: SERVICE_UNAVAILABLE - operationId: get-curbs-spaces - description: 'Optional endpoint. If not implemented, the server should reply with 501 Not Implemented.' - parameters: - - $ref: '#/components/parameters/min_lat' - - $ref: '#/components/parameters/min_lng' - - $ref: '#/components/parameters/max_lat' - - $ref: '#/components/parameters/max_lng' - - $ref: '#/components/parameters/lat' - - $ref: '#/components/parameters/lng' - - $ref: '#/components/parameters/radius' - tags: - - Curbs API - security: [] - x-stoplight: - id: uw6x7xz5yqmmo - /curbs/policies: - get: - summary: Get Curb Policies - responses: - '200': - description: Policies Found - content: - application/json: - schema: - type: object - properties: - version: - $ref: '#/components/schemas/rest-response-version' - time_zone: - $ref: '#/components/schemas/rest-response-time_zone' - last_updated: - $ref: '#/components/schemas/rest-response-last_updated' - currency: - $ref: '#/components/schemas/rest-response-currency' - author: - $ref: '#/components/schemas/rest-response-author' - license_url: - $ref: '#/components/schemas/rest-response-license_url' - data: - type: array - items: - type: object - properties: - policies: - type: array - items: - $ref: '#/components/schemas/curb_policy' - '400': - description: BAD_REQUEST - '401': - description: UNAUTHORIZED - '403': - description: FORBIDDEN - '500': - description: SERVER_ERROR - '501': - description: NOT_IMPLEMENTED - '503': - description: SERVICE_UNAVAILABLE - operationId: get-curbs-policies - description: 'Optional endpoint, but required if Curb Zones contain policy_id references. If not implemented, the server should reply with 501 Not Implemented.' - parameters: - - schema: - type: string - in: query - name: ids - description: Comma-separated list of Policy IDs. - tags: - - Curbs API - security: [] - x-stoplight: - id: 8e7iad2rt96ow - '/curbs/zones/{id}': - get: - summary: Get a single Curb Zone - responses: - '200': - description: Zone Found - content: - application/json: - schema: - type: object - properties: - version: - $ref: '#/components/schemas/rest-response-version' - time_zone: - $ref: '#/components/schemas/rest-response-time_zone' - last_updated: - $ref: '#/components/schemas/rest-response-last_updated' - currency: - $ref: '#/components/schemas/rest-response-currency' - author: - $ref: '#/components/schemas/rest-response-author' - license_url: - $ref: '#/components/schemas/rest-response-license_url' - data: - type: array - items: - type: object - properties: - zone: - $ref: '#/components/schemas/curb_zone' - '400': - description: BAD_REQUEST - '401': - description: UNAUTHORIZED - '403': - description: FORBIDDEN - '404': - description: NOT_FOUND - '500': - description: SERVER_ERROR - '501': - description: NOT_IMPLEMENTED - '503': - description: SERVICE_UNAVAILABLE - operationId: get-curbs-zone - description: 'Fetch a single Curb Zone by ID. Optional endpoint. If not implemented, the server should reply with 501 Not Implemented.' - parameters: - - schema: - type: string - name: id - in: path - required: true - description: Curb Zone ID - - schema: - $ref: '#/components/schemas/timestamp' - in: query - name: time - description: 'The Curb Zone object will only be returned if its validity period includes this time; otherwise, the server should reply with 404 Not Found.' - - schema: - type: boolean - in: query - name: show_historic - description: 'Whether to return historic, retired curb zone data.' - tags: - - Curbs API - security: [] - x-stoplight: - id: yuag4b4aqbkf1 - '/curbs/areas/{id}': - get: - summary: Get a single Curb Area - responses: - '200': - description: Area Found - content: - application/json: - schema: - type: object - properties: - version: - $ref: '#/components/schemas/rest-response-version' - time_zone: - $ref: '#/components/schemas/rest-response-time_zone' - last_updated: - $ref: '#/components/schemas/rest-response-last_updated' - currency: - $ref: '#/components/schemas/rest-response-currency' - author: - $ref: '#/components/schemas/rest-response-author' - license_url: - $ref: '#/components/schemas/rest-response-license_url' - data: - type: array - items: - type: object - properties: - area: - $ref: '#/components/schemas/curb_area' - '400': - description: BAD_REQUEST - '401': - description: UNAUTHORIZED - '403': - description: FORBIDDEN - '404': - description: NOT_FOUND - '500': - description: SERVER_ERROR - '501': - description: NOT_IMPLEMENTED - '503': - description: SERVICE_UNAVAILABLE - operationId: get-curbs-area - description: 'Fetch a single Curb Area by ID. Optional endpoint. If not implemented, the server should reply with 501 Not Implemented.' - parameters: - - schema: - type: string - name: id - in: path - required: true - description: Curb Area ID - tags: - - Curbs API - security: [] - x-stoplight: - id: ad85cej1q50dp - '/curbs/spaces/{id}': - get: - summary: Get a single Curb Space - responses: - '200': - description: Space Found - content: - application/json: - schema: - type: object - properties: - version: - $ref: '#/components/schemas/rest-response-version' - time_zone: - $ref: '#/components/schemas/rest-response-time_zone' - last_updated: - $ref: '#/components/schemas/rest-response-last_updated' - currency: - $ref: '#/components/schemas/rest-response-currency' - author: - $ref: '#/components/schemas/rest-response-author' - license_url: - $ref: '#/components/schemas/rest-response-license_url' - data: - type: array - items: - type: object - properties: - space: - $ref: '#/components/schemas/curb_space' - '400': - description: BAD_REQUEST - '401': - description: UNAUTHORIZED - '403': - description: FORBIDDEN - '404': - description: NOT_FOUND - '500': - description: SERVER_ERROR - '501': - description: NOT_IMPLEMENTED - '503': - description: SERVICE_UNAVAILABLE - operationId: get-curbs-space - description: 'Fetch a single Curb Space by ID. Optional endpoint. If not implemented, the server should reply with 501 Not Implemented.' - parameters: - - schema: - type: string - name: id - in: path - required: true - description: Curb Space ID - - schema: - $ref: '#/components/schemas/timestamp' - in: query - name: time - description: Availability data (if supplied) will be returned as of this time. - tags: - - Curbs API - security: [] - x-stoplight: - id: u19hpktf0n1hl - '/curbs/policies/{id}': - get: - summary: Get a single Curb Policy - responses: - '200': - description: Policy Found - content: - application/json: - schema: - type: object - properties: - version: - $ref: '#/components/schemas/rest-response-version' - time_zone: - $ref: '#/components/schemas/rest-response-time_zone' - last_updated: - $ref: '#/components/schemas/rest-response-last_updated' - currency: - $ref: '#/components/schemas/rest-response-currency' - author: - $ref: '#/components/schemas/rest-response-author' - license_url: - $ref: '#/components/schemas/rest-response-license_url' - data: - type: array - items: - type: object - properties: - policy: - $ref: '#/components/schemas/curb_policy' - '400': - description: BAD_REQUEST - '401': - description: UNAUTHORIZED - '403': - description: FORBIDDEN - '404': - description: NOT_FOUND - '500': - description: SERVER_ERROR - '503': - description: SERVICE_UNAVAILABLE - operationId: get-curbs-policy - description: Fetch a single Curb Policy by ID. - parameters: - - schema: - type: string - name: id - in: path - required: true - description: Curb Policy ID - tags: - - Curbs API - security: [] - x-stoplight: - id: f891w4kmcowo1 - /events/events: - get: - summary: Get Events - tags: - - Events API - responses: - '200': - description: 'OK: operation successful.' - content: - application/json: - schema: - type: object - properties: - time_zone: - $ref: '#/components/schemas/rest-response-time_zone' - version: - $ref: '#/components/schemas/rest-response-version' - last_updated: - $ref: '#/components/schemas/rest-response-last_updated' - currency: - $ref: '#/components/schemas/rest-response-currency' - author: - $ref: '#/components/schemas/rest-response-author' - license_url: - $ref: '#/components/schemas/rest-response-license_url' - data: - type: array - items: - $ref: '#/components/schemas/curb-event' - operationId: get-events-events - parameters: - - $ref: '#/components/parameters/curb_area_id' - - $ref: '#/components/parameters/curb_zone_id' - - $ref: '#/components/parameters/curb_space_id' - description: '' - x-stoplight: - id: b5ex02kdfrljo - /events/status: - get: - summary: Get Status - tags: - - Events API - responses: - '200': - description: OK - content: - application/json: - schema: - type: object - properties: - version: - $ref: '#/components/schemas/rest-response-version' - time_zone: - $ref: '#/components/schemas/rest-response-time_zone' - last_updated: - $ref: '#/components/schemas/rest-response-last_updated' - currency: - $ref: '#/components/schemas/rest-response-currency' - author: - $ref: '#/components/schemas/rest-response-author' - license_url: - $ref: '#/components/schemas/rest-response-license_url' - data: - type: object - properties: - status: - type: array - items: - type: object - properties: - data_source_device_id: - $ref: '#/components/schemas/uuid' - description: 'Unique identifier of this event source, whether sensor, vehicle, camera, etc.' - data_source_type: - $ref: '#/components/schemas/data_source_type' - description: General category of the source creating the event. - data_source_operator_id: - $ref: '#/components/schemas/operator_id' - sensor_status_is_commissioned: - type: boolean - description: 'If a sensor was used to capture this event, the commissioned status at the time that the event was reported. Indicates whether the sensor is currently in a state where it should be reporting data.' - sensor_status_is_online: - type: boolean - description: 'If a sensor was used to capture this event, the online status at the time that the event was reported. Indicates whether the sensor is currently online and reporting data.' - required: - - data_source_device_id - - data_source_type - '501': - $ref: '#/components/responses/501' - operationId: get-events-status - parameters: - - $ref: '#/components/parameters/curb_area_id' - - $ref: '#/components/parameters/curb_zone_id' - - $ref: '#/components/parameters/curb_space_id' - x-stoplight: - id: p1of272g09cjr - /metrics/sessions: - get: - summary: Get Sessions - tags: - - Metrics API - responses: - '200': - description: OK - content: - application/json: - schema: - type: object - properties: - version: - $ref: '#/components/schemas/rest-response-version' - time_zone: - $ref: '#/components/schemas/rest-response-time_zone' - last_updated: - $ref: '#/components/schemas/rest-response-last_updated' - currency: - $ref: '#/components/schemas/rest-response-currency' - author: - $ref: '#/components/schemas/rest-response-author' - license_url: - $ref: '#/components/schemas/rest-response-license_url' - data: - type: array - items: - type: object - properties: - session_type: - type: string - enum: - - parking - - area - description: The type of session that happened for this event. - event_session_id: - $ref: '#/components/schemas/uuid' - description: 'If known and recorded to tie two Events together, then include the `event_session_id` from the [Curb Event](./docs/cds-openapi/6754f1a684eb4)' - event_id_start: - $ref: '#/components/schemas/uuid' - description: The globally unique identifier of the start/enter event that occurred. - event_id_end: - $ref: '#/components/schemas/uuid' - description: The globally unique identifier of the end/exit event that occurred. - event_location_start_latitude: - $ref: '#/components/schemas/latitude' - description: The geographic latitude point location where the start/enter of the event occurred. - event_location_start_longitude: - $ref: '#/components/schemas/longitude' - description: The geographic longitude point location where the start/enter of the event occurred. - event_location_end_latitude: - $ref: '#/components/schemas/latitude' - description: The geographic latitude point location where the end/exit of the event occurred. - event_location_end_longitude: - $ref: '#/components/schemas/longitude' - description: The geographic longitude point location where the end/exit of the event occurred. - event_time_start: - $ref: '#/components/schemas/timestamp' - description: Timestamp (date/time) at which the event started with the `park_start` or `enter_area` event types. - event_time_end: - $ref: '#/components/schemas/timestamp' - description: Timestamp (date/time) at which the event occurred. - curb_area_ids: - type: array - description: 'Unique IDs of the Curb Area where the event occurred. Since Curb Areas can overlap, an event may happen in more than one. Required for events that occurred in a known Curb Area for these event_types: `enter_area`, `exit_area`, `park_start`, `park_end`.' - items: - $ref: '#/components/schemas/uuid' - curb_zone_id: - $ref: '#/components/schemas/uuid' - description: Unique ID of the Curb Zone where the event occurred. Required for events that occurred at a known Curb Zone for **ALL** event types. - curb_space_id: - $ref: '#/components/schemas/uuid' - description: 'Unique ID of the Curb Space where the event occurred. Required for events that occurred at a known Curb Space for these event_types: `park_start`, `park_end`, `enter_area`, `exit_area`.' - vehicle_length: - type: number - description: 'Approximate length of the vehicle that performed the event, in centimeters. Required for sources capable of determining vehicle length.' - vehicle_type: - $ref: '#/components/schemas/vehicle_type' - required: - - session_type - '501': - $ref: '#/components/responses/501' - operationId: get-metrics-sessions - parameters: - - $ref: '#/components/parameters/curb_place_type' - - $ref: '#/components/parameters/curb_place_id' - - $ref: '#/components/parameters/min_lat' - - $ref: '#/components/parameters/min_lng' - - $ref: '#/components/parameters/max_lat' - - $ref: '#/components/parameters/max_lng' - - $ref: '#/components/parameters/lat' - - $ref: '#/components/parameters/lng' - - $ref: '#/components/parameters/radius' - - $ref: '#/components/parameters/start_time' - - $ref: '#/components/parameters/end_time' - description: |- - ## Required Query Parameters - The following sets of query parameters are required if `ANY` parameter in the set are provided. - * `curb_place_type`, `curb_place_id` - * `min_lat`, `min_lng`, `max_lat`, `max_lng` - * `lat`, `lng`, `radius` - x-stoplight: - id: owuyr2yiwj38o - /metrics/aggregates: - get: - summary: Get Aggregates - tags: - - Metrics API - responses: - '200': - description: OK - content: - application/json: - schema: - type: object - properties: - version: - $ref: '#/components/schemas/rest-response-version' - time_zone: - $ref: '#/components/schemas/rest-response-time_zone' - last_updated: - $ref: '#/components/schemas/rest-response-last_updated' - currency: - $ref: '#/components/schemas/rest-response-currency' - author: - $ref: '#/components/schemas/rest-response-author' - license_url: - $ref: '#/components/schemas/rest-response-license_url' - data: - type: array - items: - type: object - properties: - curb_place_type: - type: string - description: The type of curb place this aggregate applies to from the Curbs API. - enum: - - area - - zone - - space - curb_place_id: - $ref: '#/components/schemas/uuid' - description: The ID of this curb place. - metric_type: - type: string - enum: - - total_sessions - - turnover - - average_dwell_time - - occupancy_percent - description: 'The metric this aggregate applies to. These calaculations are defined by the OMF in detail [here](https://github.com/openmobilityfoundation/curb-data-specification/tree/main/metrics#methodology).' - date: - type: string - description: 'The date the event occured in ISO 8601 format, local timezone, in "YYYY-MM-DD" format.' - example: '2021-04-01' - format: date - hour: - type: integer - description: 'The hour of the day the event occured in ISO 8601 format, local timezone, in "hh" format.' - example: '23' - value: - type: number - description: The results of the calculations for this metric. Note that "-1" means that the sensor/source was offline for the majority of the time. - example: '"2.9" "0.05"' - required: - - curb_place_type - - curb_place_id - - metric_type - - date - - hour - - value - required: - - version - - time_zone - - last_updated - - currency - - author - - license_url - - data - '501': - $ref: '#/components/responses/501' - operationId: get-metrics-aggregates - parameters: - - $ref: '#/components/parameters/curb_place_type' - - $ref: '#/components/parameters/curb_place_id' - - $ref: '#/components/parameters/min_lat' - - $ref: '#/components/parameters/min_lng' - - $ref: '#/components/parameters/max_lat' - - $ref: '#/components/parameters/max_lng' - - $ref: '#/components/parameters/lat' - - $ref: '#/components/parameters/lng' - - $ref: '#/components/parameters/radius' - - $ref: '#/components/parameters/start_time' - - $ref: '#/components/parameters/end_time' - description: |- - ## Required Query Parameters - The following sets of query parameters are required if `ANY` parameter in the set are provided. - * `curb_place_type`, `curb_place_id` - * `min_lat`, `min_lng`, `max_lat`, `max_lng` - * `lat`, `lng`, `radius` - x-stoplight: - id: vlnl7l63gqy1n -components: - schemas: - timestamp: - description: Timestamp in milliseconds since Epoch. - type: integer - minimum: 100000000000 - maximum: 99999999999999 - x-internal: false - title: Timestamp - x-stoplight: - id: 9h333ijy5gy1e - uuid: - type: string - format: uuid - x-internal: false - title: UUID - x-stoplight: - id: yan587cvuqppu - description: A UUID string value - latitude: - type: number - minimum: -90 - maximum: 90 - x-internal: false - title: Latitude - description: '' - x-stoplight: - id: w5n8fow8pavzx - longitude: - type: number - minimum: -180 - maximum: 180 - x-internal: false - title: Longitude - x-stoplight: - id: 1mf0ywpexjhtq - data_source_type: - title: Data Source Type - x-stoplight: - id: 807f64500e804 - type: string - enum: - - data_feed - - camera - - above_ground - - in_ground - - meter - - payment - - in_person - - other - description: The set of possible categories of sources that can publish a Curb Event. - vehicle_type: - title: Vehicle Type - x-stoplight: - id: zc8pejs5x7n8g - type: string - enum: - - bicyle - - cargo_bicycle - - car - - scooter - - moped - - motorcycle - - truck - - van - - freight - - other - - unspecified - description: |- - Type of the vehicle that performed the event. - - Required for sources capable of determining vehicle type. - operator_id: - $ref: '#/components/schemas/uuid' - x-stoplight: - id: jts5h9b4s9c8v - description: |- - Unique identifier of the entity responsible for operating the event data source. - - For example, IDs can identify a fleet operator sending a data feed, or the organization (company or city) operating the sensor. - - **Values are defined globally and are managed by the Open Mobility Foundation and operators may register [here](https://github.com/openmobilityfoundation/curb-data-specification/wiki/Adding-a-CDS-Data-Source-Operator-ID)** - title: Operator ID - examples: - - 55b617b9-730e-485e-83de-5e1a35fdc352 - curb_zone: - type: object - properties: - curb_zone_id: - allOf: - - $ref: '#/components/schemas/uuid' - - description: The ID of this Curb Zone. - geometry: - type: object - properties: - type: - type: string - coordinates: - type: array - items: - type: number - required: - - type - - coordinates - description: The spatial extent of this curb zone. - curb_policy_ids: - type: array - items: - $ref: '#/components/schemas/uuid' - description: 'An array of IDs of Policy objects. Together, these define the regulations of this Curb Zone.' - prev_policies: - type: array - items: - type: object - properties: - curb_policy_ids: - type: array - items: - $ref: '#/components/schemas/uuid' - description: 'An array of IDs of Policy objects. Together, these define the previous regulations of this Curb Zone.' - start_date: - allOf: - - $ref: '#/components/schemas/timestamp' - - description: The date/time that this policy started being active for this curb location. - end_date: - allOf: - - $ref: '#/components/schemas/timestamp' - - description: The date/time that this policy ended being active for this curb location. - required: - - curb_policy_ids - - start_date - - end_date - description: An array of information about what previous policies applied to a curb zone and when. - published_date: - allOf: - - $ref: '#/components/schemas/timestamp' - - description: The date/time that this curb zone was first published in this data feed. - last_updated_date: - allOf: - - $ref: '#/components/schemas/timestamp' - - description: The date/time that the properties of ths curb zone were last updated. - prev_curb_zone_ids: - type: array - items: - $ref: '#/components/schemas/uuid' - description: An array of IDs of previous curb zone objects. They are listed in order with the most recent ones first. - start_date: - allOf: - - $ref: '#/components/schemas/timestamp' - - description: The earliest time that the data for this curb location is known to be valid. - end_date: - allOf: - - $ref: '#/components/schemas/timestamp' - - description: The time at which the data for this curb location ceases to be valid. - location_references: - type: array - items: - type: object - properties: - source: - type: string - format: url - description: An identifier for the source of the linear reference. This MUST be a URL pointing to more information about the underlying map or reference system. - ref_id: - type: string - description: The linear feature being referenced (usually a street or curb segment). - start: - type: integer - description: The distance (in centimeters) from the start of the referenced linear feature to the start of the Curb Zone. - minimum: 0 - end: - type: integer - description: 'The distance (in centimeters) from the start of the referenced linear feature to the end of the Curb Zone. ''end'' MAY be smaller than start, implying that the direction of the Curb Zone is opposite to the direction of the referenced linear feature.' - minimum: 0 - side: - type: string - enum: - - left - - right - description: 'If the referenced linear feature is a roadway, the side of the roadway on which the Curb Zone may be found, when heading from the start to the end of the feature in its native orientation.' - required: - - source - - ref_id - - start - - end - description: 'A linear reference defines a Curb Zone''s position by reference to a linear feature, like a street centerline or edge-of-pavement line.' - description: One or more linear references for this Curb Zone. - name: - type: string - description: A human-readable name for this Curb Zone that identifies it to end users. - user_zone_id: - type: string - description: 'An identifier that can be used to refer to this Curb Zone on physical signage as well as within mobile applications, typically for payment purposes.' - street_name: - type: string - description: The name of the street that this Curb Zone is on. - cross_street_start_name: - type: string - description: The name of the cross street at or before the start of this Curb Zone. - cross_street_end_name: - type: string - description: The name of the cross street at the end of this Curb Zone. - length: - type: integer - description: 'The length, in centimeters, of the Curb Zone when projected along the street centerline. Note that this is the definitive length of the curb area, and not the edge length of the geographic polygon.' - exclusiveMinimum: 0 - available_space_lengths: - type: array - items: - type: integer - description: 'If availability information is present, an array of numbers containing the lengths (in centimeters) of all known non-overlapping available spaces within this Curb Zone.' - availability_time: - allOf: - - $ref: '#/components/schemas/timestamp' - - description: 'If availability information is present, the timestamp corresponding to the most recent time that availability was computed for this zone.' - width: - type: integer - description: 'The width, in centimeters, that the Curb Zone occupies from the curb to the roadway lane.' - exclusiveMinimum: 0 - parking_angle: - type: string - enum: - - parallel - - perpendicular - - angled - description: The angle in which passenger vehicles in this Curb Zone are meant to park. - num_spaces: - type: integer - description: The number of demarcated spaces within this Curb Zone. - street_side: - type: string - enum: - - 'N' - - NE - - E - - SE - - S - - SW - - W - - NW - description: The cardinal or subcardinal direction representing the side of the roadway that this curb is on. - median: - type: boolean - description: 'If "true", this curb location is on the median of a street, rather than its edge.' - entire_roadway: - type: boolean - description: 'If "true", this curb location takes up the entire width of the roadway (which may be impassible for through traffic when the Curb Zone is being used for parking or loading).' - curb_area_ids: - type: array - items: - $ref: '#/components/schemas/uuid' - description: The ID(s) of the Curb Areas that this Curb Zone is a part of. - curb_space_ids: - type: array - items: - $ref: '#/components/schemas/uuid' - description: The ID(s) of the Curb Spaces that this Curb Zone contains. - required: - - curb_zone_id - - geometry - - curb_policy_ids - - published_date - - last_updated_date - - start_date - example: - curb_zone_id: 7d8a5885-e949-4ac9-afb7-fa4d43b68530 - geometry: - type: Polygon - coordinates: - - - - -73.982105 - - 40.767932 - - - -73.973694 - - 40.764551 - - - -73.949318 - - 40.796918 - - - -73.958416 - - 40.800686 - - - -73.982105 - - 40.767932 - curb_policy_ids: - - cd0996d7-3765-4f0b-a72e-7caf7cf3fe21 - published_date: 1552678594428 - last_updated_date: 1552678594428 - start_date: 1552678594428 - description: A contiguous region of curb space on a single block face that is regulated in a particular way. - x-internal: false - x-stoplight: - id: 202654569fa9e - title: Model - Curb Zone - curb_area: - type: object - properties: - curb_area_id: - allOf: - - $ref: '#/components/schemas/uuid' - - description: The ID for the Curb Area. - geometry: - type: object - properties: - type: - type: string - coordinates: - type: array - items: - type: number - required: - - type - - coordinates - description: The spatial extent of this curb location. - name: - type: string - description: The name of this curb area for reference. - published_date: - allOf: - - $ref: '#/components/schemas/timestamp' - - description: The date/time that this curb area was first published in this data feed. - last_updated_date: - allOf: - - $ref: '#/components/schemas/timestamp' - - description: The date/time that the properties of ths curb area were last updated. - curb_zone_ids: - type: array - items: - $ref: '#/components/schemas/uuid' - description: The IDs of all the Curb Zones included within this Curb Area at the requested time. - required: - - curb_area_id - - geometry - - published_date - - last_updated_date - - curb_zone_ids - example: - curb_area_id: 91eb651d-f91f-4ba2-9553-75ca368c7e1f - geometry: - type: Polygon - coordinates: - - - - -73.982105 - - 40.767932 - - - -73.973694 - - 40.764551 - - - -73.949318 - - 40.796918 - - - -73.958416 - - 40.800686 - - - -73.982105 - - 40.767932 - name: Central business district - published_date: 1552678594428 - last_updated_date: 1552678594428 - curb_zone_ids: - - 7d8a5885-e949-4ac9-afb7-fa4d43b68530 - description: A particular neighborhood or area of interest that includes one or more Curb Zones. - title: Model - Curb Area - x-internal: false - x-stoplight: - id: e2235c918423f - curb_space: - type: object - properties: - curb_space_id: - allOf: - - $ref: '#/components/schemas/uuid' - - description: The ID of the Curb Space. - geometry: - type: object - properties: - type: - type: string - coordinates: - type: array - items: - type: number - required: - - type - - coordinates - description: The spatial extent of this curb location. - name: - type: string - description: The name of this curb space for reference. - published_date: - allOf: - - $ref: '#/components/schemas/timestamp' - - description: The date/time that this curb area was first published in this data feed. - last_updated_date: - allOf: - - $ref: '#/components/schemas/timestamp' - - description: The date/time that the properties of ths curb area were last updated. - curb_zone_id: - allOf: - - $ref: '#/components/schemas/uuid' - - description: The ID of the Curb Zone this space is within. - space_number: - type: integer - description: 'The sequence number of this space within its Zone. If specified, two spaces within the same Curb Zone MUST NOT share a space number, and space numbers SHOULD be consecutive positive integers starting at 1.' - length: - type: integer - description: Length in centimeters of this Space. - width: - type: integer - description: Width in centimeters of this Space. - available: - type: boolean - description: Whether this space is available for vehicles to park in at the specified time. - availability_time: - allOf: - - $ref: '#/components/schemas/timestamp' - - description: 'If availability information is present, the most recent time that availability was computed for this space.' - required: - - curb_space_id - - geometry - - published_date - - last_updated_date - - curb_zone_id - - length - example: - curb_space_id: 47c877ce-2670-4300-9ec2-6a1f3af707b6 - geometry: - type: Polygon - coordinates: - - - - -73.982105 - - 40.767932 - - - -73.973694 - - 40.764551 - - - -73.949318 - - 40.796918 - - - -73.958416 - - 40.800686 - - - -73.982105 - - 40.767932 - name: A487 - published_date: 1552678594428 - last_updated_date: 1552678594428 - curb_zone_id: 7d8a5885-e949-4ac9-afb7-fa4d43b68530 - space_number: 487 - length: 550 - width: 260 - available: false - availability_time: 1657213115826 - description: An individual demarcated space within a Curb Zone. - x-internal: false - x-stoplight: - id: acc7fbb358869 - title: Model - Curb Space - curb_policy: - type: object - example: - curb_policy_id: cd0996d7-3765-4f0b-a72e-7caf7cf3fe21 - published_date: 1552678594428 - priority: 1 - data_source_operator_id: - - b2046faf-2bc2-4f0e-b784-7cc746138555 - - aba63473-351c-4624-93ab-456db34f83a6 - - 984cae91-3a11-49eb-b68c-d325a6cc8970 - time_spans: - - days_of_week: - - mon - - tue - - wed - - thu - - fri - time_of_day_start: '10:00' - time_of_day_end: '16:00' - rules: - - activity: parking - max_stay: 15 - user_classes: - - rideshare - - electric - description: An object that allows or prohibits a particular set of users from using a particular curb at a particular time or times. - x-stoplight: - id: a3aab507b1c7e - title: Model - Curb Policy - properties: - curb_policy_id: - $ref: '#/components/schemas/uuid' - description: An ID that uniquely identifies this exact policy across Curb Zones. - published_date: - $ref: '#/components/schemas/timestamp' - priority: - type: integer - description: 'Specifies which other policies this one takes precedence over. If two Policies on the same Curb Zone have overlapping Time Spans and apply to the same user class, the one that applies at a given time is the one with the lowest priority.' - rules: - type: array - description: The rule(s) that this policy applies. - items: - type: object - description: 'A rule defines who is allowed to do what, and for how long, on a curb, per the policy.' - properties: - activity: - type: string - enum: - - parking - - no parking - - loading - - no loading - - unloading - - no unloading - - stopping - - no stopping - - travel - - no travel - description: The activity that is forbidden or permitted by this regulation. - max_stay: - type: integer - description: 'The length of time (in units of max_stay_unit) for which the curb may be used under this regulation. If not specified, the curb may be used under this regulation indefinitely.' - max_stay_unit: - $ref: '#/components/schemas/unit-of-time' - no_return: - type: integer - description: The length of time (in units of no_return_unit) that a user must vacate a Curb Zone before being allowed to return for another stay. - no_return_unit: - $ref: '#/components/schemas/unit-of-time' - description: The Unit of Time associated with the no_return value. - user_classes: - type: array - description: A user class represents any class of vehicles that is regulated by a city with respect to curb space. - items: - type: string - enum: - - bicycle - - bus - - cargo_bicycle - - car - - moped - - motorcycle - - scooter - - truck - - van - - handicap-accessible - - human - - electric_assist - - electric - - combustion - - autonomous - - construction - - delivery - - emergency_use - - freight - - parking - - permit - - rideshare - - school - - service_vehicles - - special_events - - taxi - - utilities - - vending - - waste_management - rate: - type: array - description: The cost of using this Curb Zone when this regulation applies. - items: - type: object - description: A Rate defines the amount a user of the curb needs to pay when a given rule applies. - properties: - rate: - type: integer - description: The rate for this space in cents (or the smallest denomination of local currency) per rate_unit. - rate_unit: - $ref: '#/components/schemas/unit-of-time' - description: The unit of time associated with the rate. - rate_unit_period: - type: string - enum: - - rolling - - calendar - description: The period of time that the rate_unit covers. - increment_duration: - type: integer - description: 'If specified, this is the smallest number of rate_units a user can pay for.' - increment_amount: - type: integer - description: 'If specified, the rate for this space is rounded up to the nearest increment of this amount, specified in the same currency units as rate.' - start_duration: - type: integer - description: The number of rate_units the vehicle must have already been present in the Curb Zone before this rate starts applying. - end_duration: - type: integer - description: The number of rate_units after which the rate stops applying. - required: - - rate - - rate_unit - required: - - activity - time_spans: - type: array - description: 'If specified, this regulation only applies at the times defined within.' - items: - type: object - description: 'A Time Span defines a period of time (that may occur once or repeatedly) during which a given regulation applies. When multiple fields are combined, all criteria must be met in order for a given Time Span to apply.' - properties: - start_date: - $ref: '#/components/schemas/timestamp' - end_date: - $ref: '#/components/schemas/timestamp' - days_of_week: - type: string - enum: - - sun - - mon - - tue - - wed - - thu - - fri - - sat - description: An array of days of the week when this Time Span applies. - days_of_month: - type: array - description: An array of days of the month when this Time Span applies. - items: - type: integer - minimum: 1 - maximum: 31 - months: - type: array - description: 'If specified, this Time Span applies only during these months (1=January, 12=December).' - items: - type: integer - minimum: 1 - maximum: 12 - time_of_day_start: - type: string - description: 'The local time that this Time Span starts to apply, as 24-hour "HH:MM".' - time_of_day_end: - type: string - description: 'The local time that this Time Span stops applying, as 24-hour "HH:MM".' - designated_period: - type: string - enum: - - snow emergency - - holidays - - school days - - game days - description: 'A string representing an arbitrarily-named, externally-defined period of time.' - designated_period_except: - type: boolean - description: 'If specified and true, this Time Span applies at all times not matching the named designated period.' - data_source_operator_id: - type: array - description: An array of Data Source Operator IDs that this policy only applies to. - items: - $ref: '#/components/schemas/operator_id' - required: - - curb_policy_id - - published_date - - priority - - rules - curb-event: - title: Model - Curb Event - x-stoplight: - id: cb0b7ebce9771 - type: object - properties: - event_id: - $ref: '#/components/schemas/uuid' - description: The globally unique identifier of the event that occurred. - event_type: - type: string - enum: - - comms_lost - - comms_restored - - decommissioned - - park_start - - park_end - - scheduled_report - - enter_area - - exit_area - description: |- - The type of event that has occurred. - - Possible values are defined in an enumeration. - event_purpose: - type: string - enum: - - construction - - delivery - - emergency_use - - parking - - passenger_transport - - special_events - - waste_management - - device_maintenance - - autonomous - - ems - - fire - - food_delivery - - parcel_delivery - - police - - public_transit - - ride_hail - - road_maintenance - - service_vehicles - - taxi - - utility_work - - vehicle_charging - - vehicle_parking - - vending - - unspecified - description: |- - **Conditionally Required** - - General event purpose that the vehicle performed during its event, discernible by observation, sensors, or self-reported in copany data feeds. New event purposes MAY be generated to reflect local curb uses, but when possible, the following well-known recommended values should be used. It may not always be knowable, but where it is possible this information should be conveyed. - - If multiple purposes apply, then use the more descriptive/specific value. - event_location: - type: string - description: The geographic point location where the event occurred. - event_time: - $ref: '#/components/schemas/timestamp' - event_publication_time: - $ref: '#/components/schemas/timestamp' - description: Time at which the event became available for consumption by this API. - event_session_id: - $ref: '#/components/schemas/uuid' - description: 'May be provided to tie known connected `park_start`and `park_end` event types together by a unique session ID. ' - curb_area_ids: - type: array - description: 'Unique IDs of the Curb Area(s) where the event occurred. Since Curb Areas may overlap, an event may occur in more than one. ' - items: - $ref: '#/components/schemas/uuid' - curb_zone_id: - $ref: '#/components/schemas/uuid' - description: | - Unique ID of the Curb Zone where the event occurred. - - Required for events that occurred at a known Curb Zone for ALL event_types. - curb_space_id: - $ref: '#/components/schemas/uuid' - description: | - Unique ID of the Curb Space where the event occured. - - Required for events that occurred at a known Curb Space, if known and used, for these event types: - * `park_start` - - * `park_end` - - * `enter_area` - - * `exit_area` - data_source_type: - $ref: '#/components/schemas/data_source_type' - description: The set of possible categories of sources that are sending this event. ' - data_source_operator_id: - $ref: '#/components/schemas/operator_id' - description: |- - Unique identifier of the entity responsible for operating the event data source. - - For example, IDs can identify a fleet operator sending a data feed, or the organization (company or city) operating the sensor. - - **Values are defined globally and are managed by the Open Mobility Foundation and operators may register [here](https://github.com/openmobilityfoundation/curb-data-specification/wiki/Adding-a-CDS-Data-Source-Operator-ID)** - data_source_operator_name: - type: string - description: |- - Name of the provider responsible for operating the vehicle, device, or sensor at the time of the event. - - May be sent along with `data_source_operator_id` or on its own for small operators at the discretion of the city. - data_source_device_id: - type: string - description: |- - Unique identifier of this event source, whether sensor, vehicle, camera, etc. Allows agencies to connect related Events as they are recorded by the same source. - - If coming from a provider, this is a generated UUID they use and not the same as the external vehicle_id. - - **If this field is needed for your use cases, review the OMF's [Privacy Guidance](https://github.com/openmobilityfoundation/curb-data-specification/blob/main/README.md#data-privacy).** - data_source_manufacturer: - type: string - description: Manufacturer of the data source hardware or vehicle reporting event data. - data_source_model: - type: string - description: Manufacturer of the data source hardware or vehicle reporting event data. - sensor_status_is_commissioned: - type: boolean - description: |- - If a sensor was used to capture this event, the commissioned status at the time that the event was reported. - - Indicates whether the sensor is currently in a state where it should be reporting data. - sensor_status_is_online: - type: boolean - description: |- - If a sensor was used to capture this event, the online status at the time that the event was reported. - - Indicates whether the sensor is currently online and reporting data. - sensor_status_is_online - copy: - type: boolean - description: |- - If a sensor was used to capture this event, the online status at the time that the event was reported. - - Indicates whether the sensor is currently online and reporting data. - vehicle_id: - type: string - description: |- - A vehicle identifier visible externally on the vehicle itself. - - **If this field is needed for your use cases, review the OMF's [Privacy Guidance](https://github.com/openmobilityfoundation/curb-data-specification/blob/main/README.md#data-privacy).** - vehicle_license_plate: - type: string - description: |- - The consistently placed vehicle license plate, usable by ALPR systems, when required for curb use. - - This field is potentially sensitive (depending on local, state, and national laws) and a data privacy framework is recommended for collecting, retention, deletion, obfuscation, and security. If this field is needed for your use cases, review our [Privacy Guidance](https://github.com/openmobilityfoundation/curb-data-specification/blob/main/README.md#data-privacy) - vehicle_permit_number: - type: string - description: 'If applicable, the assigned permit numbe for this vehicle from the city agency.' - vehicle_length: - type: integer - description: |- - Appoximate length of the vehicle that performed the event, in centimeters. - - Required for sources capable of determining vehicle length. - vehicle_type: - $ref: '#/components/schemas/vehicle_type' - description: |- - Type of the vehicle that performed the event. - - Required for sources capable of determining vehicle type. - vehicle_propulsion_types: - type: string - enum: - - human - - electric_assist - - electric - - combustion - description: |- - List of propulsion types used by the vehicle that performed the event. - - Required for sources capable of determining vehicle propulsion type. - vehicle_blocked_lane_types: - type: string - description: |- - Type(s) of lane blocked by the vehicle performing the event. If no lanes are blocked by the vehicle performing the event, the array should be empty. - - Required for sources capable of determining it for the following event_types: `park_start` - enum: - - travel_lane - - turn_lane - - bike_lane - - bus_lane - - parking - - shoulder - - median - - sidewalk - - unspecified - curb_occupants: - type: object - description: |- - Current occupants of the Curb Zone. If the sensor is capable of identifying the linear location of the vehicle, then elements are sorted in ascending order according to the start property of the linear reference. Otherwise, elements appear in no particular order. - - Required for sources capable of determining it for the following event_types: `park_start`, `park_end`, `scheduled_report` - properties: - type: - $ref: '#/components/schemas/vehicle_type' - length: - type: number - description: |- - The approximate length in centimeters of the vehicle. - - Required when the event source is capable of determining vehicle length. - linear_location: - type: array - description: |- - A two-element array that specifies the start and end of the occupant’s linear location relative to the start of the Curb Zone in that order. - - Required when the event source is capable of determining the linear location of occupants. - minItems: 2 - maxItems: 2 - items: - type: number - minimum: 0 - maximum: 0 - actual_cost: - type: integer - description: |- - If available from the source, the actual cost, in the currency defined in currency, paid by the curb user for this event. - - All costs should be given as integers in the currency's smallest unit. As an example, to represent $1 USD, specify an amount of 100 (for 100 cents). - required: - - event_id - - event_type - - event_location - - event_time - - event_publication_time - - data_source_type - - data_source_device_id - unit-of-time: - description: An enumeration for units of time. - type: string - enum: - - second - - minute - - hour - - day - - week - - month - - year - x-internal: false - title: Unit of Time - x-stoplight: - id: t22vz53uc0i6g - rest-response-time_zone: - title: REST Response - Time Zone - type: string - description: |- - This is a standard value that must be returned in the body of all API endpoints. - - The time zone that applies to parking regulations in this dataset. - - MUST be a valid [TZ database time zone name](https://www.iana.org/time-zones) (ex: "US/Eastern" or "Europe/Paris"). - x-internal: false - x-stoplight: - id: d9ojycvukf3ny - rest-response-version: - title: REST Response - Version - x-stoplight: - id: 3bxwqr73eu79g - type: string - description: |- - This is a standard value that must be returned in the body of all API endpoints. - - The version of CDS that the API conforms to. - example: 1.0.0 - x-internal: false - rest-response-last_updated: - $ref: '#/components/schemas/timestamp' - x-stoplight: - id: mwudsha7oso9v - description: |- - This is a standard value that must be returned in the body of all API endpoints. - - The last time the data in this API was updated. - x-internal: false - title: REST Response - Last Updated - rest-response-currency: - title: REST Response - Currency - x-stoplight: - id: 1y7ea7wbdav1u - type: string - description: |- - This is a standard value that must be returned in the body of all API endpoints. - - The ISO 4217 3-letter code for the currency in which rates for curb usage are denominated. All costs should be given as integers in the currency's smallest unit. As an example, to represent `$1 USD`, specify an amount of `100` (for 100 cents). - example: '100' - x-internal: false - rest-response-author: - title: REST Response - Author - x-stoplight: - id: mhmufpclryjhz - type: string - description: |- - This is a standard value that must be returned in the body of all API endpoints. - - The name of the organization that produces and maintains this data. - x-internal: false - rest-response-license_url: - title: REST Response - License URL - x-stoplight: - id: beyxkbcgpflk1 - type: string - description: |- - This is a standard value that must be returned in the body of all API endpoints. - - The licensing terms under which this data is provided. - x-internal: false - securitySchemes: - JSON Web Token: - name: Authorization - type: apiKey - in: header - description: |- - SON Web Token ([JWT](https://jwt.io/introduction/)) is **RECOMMENDED** as the token format. - - JWTs provide a safe, secure way to verify the identity of an agency and provide access to MDS resources without providing access to other, potentially sensitive data. - - Implementers **MAY** include any metadata in the JWT they wish that helps to route, log, permission, or debug agency requests, leaving their internal implementation flexible. - OAuth 2.0: - type: oauth2 - flows: - clientCredentials: - tokenUrl: '' - refreshUrl: '' - scopes: {} - description: |- - OAuth 2.0's `client_credentials` grant type (outlined in [RFC6749](https://tools.ietf.org/html/rfc6749#section-4.4)) is **RECOMMENDED** as the authentication and authorization scheme. - - OAuth 2.0 is an industry standard authorization framework with a variety of existing tooling. The client_credentials grant type facilitates generation of tokens that can be used for access by agencies and distributed to data partners. - - If implementers use this auth scheme, they **MAY** choose to specify token scopes that define access parameters like allowable time ranges. These guidelines **SHOULD** be encoded into the returned token in a parseable way. - responses: - '501': - description: Not Implemented - content: - application/json: - schema: - properties: - id: - type: string - parameters: - curb_place_type: - name: curb_place_type - in: query - required: false - schema: - type: string - description: '**Required with `curb_place_id`.** The type of curb place this aggregate applies to from the Curbs API: area, zone, space. ' - curb_place_id: - name: curb_place_id - in: query - required: false - schema: - type: string - description: '**Required with `curb_place_id`.** The type of curb place this aggregate applies to from the Curbs API: area, zone, space. ' - min_lat: - name: min_lat - in: query - required: false - schema: - type: string - description: 'Used to specify a latitude and longitude bounding box. Must be used together with `min_lng`, `max_lat`, and `max_lng`. If specified only return locations that intersect the supplied bounding box. This parameter is incompatible with `lat`, `lng`, and `radius`.' - min_lng: - name: min_lng - in: query - required: false - schema: - type: string - description: 'Used to specify a latitude and longitude bounding box. Must be used together with `min_lat`, `max_lat`, and `max_lng`. If specified only return locations that intersect the supplied bounding box. This parameter is incompatible with `lat`, `lng`, and `radius`.' - max_lat: - name: max_lat - in: query - required: false - schema: - type: string - description: 'Used to specify a latitude and longitude bounding box. Must be used together with `min_lat`, `min_lng`, and `max_lng`. If specified only return locations that intersect the supplied bounding box. This parameter is incompatible with `lat`, `lng`, and `radius`.' - max_lng: - name: max_lng - in: query - required: false - schema: - type: string - description: 'Used to specify a latitude and longitude bounding box. Must be used together with `min_lat`, `min_lng`, and `max_lat`. If specified only return locations that intersect the supplied bounding box. This parameter is incompatible with `lat`, `lng`, and `radius`.' - lat: - name: lat - in: query - required: false - schema: - type: string - description: 'Specifies a latitude and longitude bounding point and a radius away from that point. Must be used together with `lng` and `radius`. Returns only locations that are within radius centimeters of the point identified by lat/lng. Curb Zones in the response MUST be ordered ascending by distance from the center point. This parameter is incompatible with `min_lat`, `min_lng`, `max_lat`, and `max_lng`' - lng: - name: lng - in: query - required: false - schema: - type: string - description: 'Specifies a latitude and longitude bounding point and a radius away from that point. Must be used together with `lat` and `radius`. Returns only locations that are within radius centimeters of the point identified by lat/lng. Curb Zones in the response MUST be ordered ascending by distance from the center point. This parameter is incompatible with `min_lat`, `min_lng`, `max_lat`, and `max_lng`' - radius: - name: radius - in: query - required: false - schema: - type: string - description: 'Specifies a latitude and longitude bounding point and a radius away from that point. Must be used together with `lng` and `lng`. Returns only locations that are within radius centimeters of the point identified by lat/lng. Curb Zones in the response MUST be ordered ascending by distance from the center point. This parameter is incompatible with `min_lat`, `min_lng`, `max_lat`, and `max_lng`' - start_time: - name: start_time - in: query - required: false - schema: - type: string - description: The start of the time period to return data where the value is inclusive. - end_time: - name: end_time - in: query - required: false - schema: - type: string - description: The end of the time period to return data where the value is inclusive. - curb_area_id: - name: curb_area_id - in: query - required: false - schema: - type: string - description: 'The ID of a Curb Area. If specified, only return records occurring within this area.' - curb_zone_id: - name: curb_zone_id - in: query - required: false - schema: - type: string - description: 'The ID of a Curb Zone. If specified, only return records occurring within this zone.' - curb_space_id: - name: curb_space_id - in: query - required: false - schema: - type: string - description: 'The ID of a Curb Space. If specified, only return records occurring within this area.' diff --git a/toc.json b/toc.json index 3a67ddd..3f5bd05 100644 --- a/toc.json +++ b/toc.json @@ -39,6 +39,11 @@ "title": "Curb Space", "uri": "/Shared Data Models/curb_space.yaml" }, + { + "type": "item", + "title": "Curb Object", + "uri": "/Shared Data Models/curb_object.yaml" + }, { "type": "item", "title": "Curb Policy", @@ -58,6 +63,11 @@ "title": "Aggregate", "uri": "/Shared Data Models/aggregate.yaml" }, + { + "type": "item", + "title": "Custom Attributes", + "uri": "/Shared Data Models/custom_attributes.yaml" + }, { "type": "item", "title": "Coordinates", @@ -78,6 +88,11 @@ "title": "Data Source Type", "uri": "/Shared Data Models/data_source_type.yaml" }, + { + "type": "item", + "title": "Enforcement", + "uri": "/Shared Data Models/enforcement.yaml" + }, { "type": "item", "title": "Event Purpose", @@ -88,6 +103,11 @@ "title": "Event Type", "uri": "/Shared Data Models/event_type.yaml" }, + { + "type": "item", + "title": "External Reference", + "uri": "/Shared Data Models/external_reference.yaml" + }, { "type": "item", "title": "GeoJSON Point", @@ -98,6 +118,11 @@ "title": "GeoJSON Polygon", "uri": "/Shared Data Models/geoJSON_polygon.yaml" }, + { + "type": "item", + "title": "GeoJSON LineString", + "uri": "/Shared Data Models/geoJSON_linestring.yaml" + }, { "type": "item", "title": "Lane Type", @@ -118,6 +143,16 @@ "title": "Operator ID", "uri": "/Shared Data Models/operator_id.yaml" }, + { + "type": "item", + "title": "Payment Channel", + "uri": "/Shared Data Models/payment_channel.yaml" + }, + { + "type": "item", + "title": "Payment Method", + "uri": "/Shared Data Models/payment_method.yaml" + }, { "type": "item", "title": "Propulsion Type", @@ -153,6 +188,11 @@ "title": "Vehicle Type", "uri": "/Shared Data Models/vehicle_type.yaml" }, + { + "type": "item", + "title": "Violation", + "uri": "/Shared Data Models/violation.yaml" + }, { "type": "divider", "title": "Shared API Responses" @@ -188,4 +228,4 @@ "uri": "/Rest Responses/rest_response_last_updated.yaml" } ] -} \ No newline at end of file +}