openapi: 3.1.0 info: title: char.gy Open Charge Point Data API version: '2026-07-27' summary: >- char.gy's statutory open data feed — an unauthenticated, OCPI-shaped Locations and Tariffs surface published to satisfy Part 4 regulation 10 of the UK Public Charge Point Regulations 2023. description: >- char.gy publishes no OpenAPI of its own; its entire published documentation for this API is a single Freshdesk help-centre article naming the host and two paths. This description was GENERATED by API Evangelist from live, anonymous HTTP probes of the two published endpoints on 2026-07-27 — every path, query parameter, response header, status code and schema field below was observed in a real response, and nothing here was inferred from the OCPI specification alone. Observed behaviour: both endpoints answer HTTP 200 with `application/json` to a request carrying no credential, no cookie and no referer. Responses use the OCPI envelope `{data, status_code, status_message, timestamp}` with `status_code: 1000` on success. Pagination is limit/offset via query string, surfaced with `x-total-count`, `x-limit` and an RFC 5988 `Link` header carrying `rel="next"`. `date_from` and `date_to` filters are implemented and were verified to change `x-total-count` (5409 unfiltered, 2396 for `date_from=2026-07-27T00:00:00Z`, 6 for `date_to=2026-07-01T00:00:00Z`, 0 for `date_from=2027-01-01T00:00:00Z`). Bad parameter values return HTTP 200 with an OCPI client error envelope (`status_code: 2001`), not a 4xx. Only GET and HEAD are routed; OPTIONS and POST return 404. There is no `/open-ocpi/versions` endpoint (404), so no OCPI version is declared, and the sessions, cdrs, tokens, commands and credentials modules are all 404 under `/open-ocpi` — only the two modules the regulation compels are open. Enumerations below are constrained to values actually observed across a 250-location sample spanning offsets 0, 1000, 2500, 4000 and 5350; where the observed value diverges from the OCPI 2.2.1 standard (notably EVSE `status` values `WORKING` and `FAULTED`, which are not in the OCPI EVSEStatus enumeration and appear to encode the regulator's "working" vocabulary from regulation 10(6)(a)) the observed value is recorded, not corrected. contact: name: char.gy Support email: support@char.gy url: https://help.char.gy/ termsOfService: https://char.gy/us/terms-of-use x-apievangelist-method: generated x-apievangelist-source: >- Live anonymous probes of https://char.gy/open-ocpi/locations and https://char.gy/open-ocpi/tariffs, 2026-07-27 x-regulatory-basis: https://www.legislation.gov.uk/uksi/2023/1168/regulation/10/made externalDocs: description: char.gy help-centre article — Public Charge Point Regulations 2023 url: https://help.char.gy/support/solutions/articles/77000576948-public-charge-point-regulations-2023 servers: - url: https://char.gy/open-ocpi description: Production open data host (no authentication) tags: - name: Locations description: Reference and availability data for char.gy charge points. - name: Tariffs description: Published price components for char.gy charging sessions. paths: /locations: get: tags: [Locations] operationId: listLocations summary: List charge point locations description: >- Returns the paginated list of char.gy charge point locations with their EVSEs and connectors. Observed anonymously with HTTP 200 and an `x-total-count` of 5409 on 2026-07-27. Every EVSE carries an `evse_id` of the form `GB*CGY*E*NNNNN`; every connector carries `tariff_ids` that resolve against `/tariffs`. security: [] parameters: - $ref: '#/components/parameters/limit' - $ref: '#/components/parameters/offset' - $ref: '#/components/parameters/dateFrom' - $ref: '#/components/parameters/dateTo' responses: '200': description: >- OCPI envelope. `status_code` is 1000 on success; malformed parameters also return HTTP 200 but with a 2xxx client error status_code and no `data` member. headers: x-total-count: $ref: '#/components/headers/XTotalCount' x-limit: $ref: '#/components/headers/XLimit' link: $ref: '#/components/headers/Link' x-request-id: $ref: '#/components/headers/XRequestId' etag: $ref: '#/components/headers/ETag' content: application/json: schema: oneOf: - $ref: '#/components/schemas/LocationListResponse' - $ref: '#/components/schemas/ErrorResponse' examples: success: summary: Two locations (observed 2026-07-27, limit=2) externalValue: ../examples/chargy-locations-response.json badLimit: summary: Non-numeric limit (observed 2026-07-27) value: status_code: 2001 status_message: Limit is not a number timestamp: '2026-07-27T21:10:38Z' /tariffs: get: tags: [Tariffs] operationId: listTariffs summary: List charging tariffs description: >- Returns the published tariff objects referenced by connector `tariff_ids` on `/locations`. Observed anonymously with HTTP 200 and an `x-total-count` of 3 on 2026-07-27, including a GBP time-of-day tariff with weekday off-peak, weekday peak and weekend restrictions. security: [] parameters: - $ref: '#/components/parameters/limit' - $ref: '#/components/parameters/offset' - $ref: '#/components/parameters/dateFrom' - $ref: '#/components/parameters/dateTo' responses: '200': description: OCPI envelope carrying tariff objects. headers: x-total-count: $ref: '#/components/headers/XTotalCount' x-limit: $ref: '#/components/headers/XLimit' link: $ref: '#/components/headers/Link' x-request-id: $ref: '#/components/headers/XRequestId' etag: $ref: '#/components/headers/ETag' content: application/json: schema: oneOf: - $ref: '#/components/schemas/TariffListResponse' - $ref: '#/components/schemas/ErrorResponse' examples: success: summary: All three tariffs (observed 2026-07-27) externalValue: ../examples/chargy-tariffs-response.json components: parameters: limit: name: limit in: query required: false description: >- Page size. Default 50 (observed via the `x-limit` response header on an unparameterised request). A non-numeric value returns status_code 2001. schema: type: integer default: 50 offset: name: offset in: query required: false description: >- Zero-based record offset. An offset beyond the collection returns an empty `data` array with status_code 1000. schema: type: integer default: 0 dateFrom: name: date_from in: query required: false description: >- Return only objects with `last_updated` at or after this timestamp. Verified functional — `date_from=2026-07-27T00:00:00Z` reduced `x-total-count` from 5409 to 2396. An unparseable value returns status_code 2001 "Date from is not a valid timestamp". schema: type: string format: date-time dateTo: name: date_to in: query required: false description: >- Return only objects with `last_updated` before this timestamp. Verified functional — `date_to=2026-07-01T00:00:00Z` returned an `x-total-count` of 6. schema: type: string format: date-time headers: XTotalCount: description: Total number of objects matching the query, before pagination. schema: type: integer example: 5409 XLimit: description: Page size applied to this response. schema: type: integer example: 50 Link: description: RFC 5988 pagination link; carries rel="next" when more pages exist. schema: type: string example: ; rel="next" XRequestId: description: Per-request correlation id emitted on every response. schema: type: string example: 48324f0b-2c70-4f8d-9d97-deb08a76770e ETag: description: Weak validator; responses are sent with cache-control private, must-revalidate. schema: type: string schemas: OcpiEnvelope: type: object description: The OCPI response envelope observed on every 200 response. required: [status_code, status_message, timestamp] properties: status_code: type: integer description: OCPI status code. 1000 = Success; 2001 observed for invalid parameters. example: 1000 status_message: type: string example: Success timestamp: type: string format: date-time example: '2026-07-27T21:10:22Z' ErrorResponse: allOf: - $ref: '#/components/schemas/OcpiEnvelope' description: >- Client-error envelope returned with HTTP 200 and no `data` member. Observed messages: "Limit is not a number", "Date from is not a valid timestamp". LocationListResponse: allOf: - $ref: '#/components/schemas/OcpiEnvelope' - type: object required: [data] properties: data: type: array items: $ref: '#/components/schemas/Location' TariffListResponse: allOf: - $ref: '#/components/schemas/OcpiEnvelope' - type: object required: [data] properties: data: type: array items: $ref: '#/components/schemas/Tariff' Location: type: object description: An OCPI-shaped charge point location. Fields as observed. required: - country_code - party_id - id - parking_type - publish - name - address - city - postal_code - country - coordinates - evses - operator - time_zone - opening_times - last_updated properties: country_code: type: string example: GB party_id: type: string description: OCPI party identifier for char.gy. example: CGY id: type: string format: uuid example: 98632dfb-6751-45ec-b3a0-9066b749fdfa parking_type: type: string description: Only ON_STREET was observed across the 250-location sample. enum: [ON_STREET] example: ON_STREET publish: type: boolean name: type: string example: Opposite 25 Grovelands Road address: type: string example: Grovelands Road city: type: string example: Haringey postal_code: type: string example: N15 6BT country: type: string description: ISO 3166-1 alpha-3. example: GBR coordinates: $ref: '#/components/schemas/GeoLocation' evses: type: array items: $ref: '#/components/schemas/EVSE' operator: $ref: '#/components/schemas/BusinessDetails' owner: allOf: - $ref: '#/components/schemas/BusinessDetails' description: >- Usually the local authority that owns the street furniture (Tower Hamlets, Southwark, Merton, Haringey, Buckinghamshire County Council observed); sometimes char.gy itself. Absent on roughly 40 percent of sampled records. time_zone: type: string example: Europe/London opening_times: $ref: '#/components/schemas/Hours' last_updated: type: string format: date-time GeoLocation: type: object description: Coordinates are strings, as observed. required: [latitude, longitude] properties: latitude: type: string example: '51.5784972' longitude: type: string example: '-0.0641408' BusinessDetails: type: object required: [name] properties: name: type: string example: char.gy website: type: string format: uri example: https://char.gy Hours: type: object properties: twentyfourseven: type: boolean description: Only twentyfourseven true was observed. EVSE: type: object required: [uid, evse_id, status, capabilities, connectors, last_updated] properties: uid: type: string format: uuid evse_id: type: string description: eMI3-style EVSE identifier issued under the GB*CGY operator prefix. example: GB*CGY*E*00022 status: type: string description: >- Observed values only. Neither WORKING nor FAULTED appears in the OCPI 2.2.1 EVSEStatus enumeration; they align instead with the "working" vocabulary of regulation 10(6)(a) of the Public Charge Point Regulations 2023. Recorded as observed, not corrected. enum: [WORKING, FAULTED] example: WORKING capabilities: type: array items: type: string enum: [REMOTE_START_STOP_CAPABLE, UNLOCK_CAPABLE] connectors: type: array items: $ref: '#/components/schemas/Connector' physical_reference: type: string example: '00022' last_updated: type: string format: date-time Connector: type: object required: [id, standard, format, power_type, max_voltage, max_amperage, last_updated] properties: id: type: string example: '1' standard: type: string description: IEC 62196 Type 2 was the only standard observed. enum: [IEC_62196_T2] format: type: string enum: [SOCKET] power_type: type: string enum: [AC_1_PHASE] max_voltage: type: integer example: 230 max_amperage: type: integer example: 22 tariff_ids: type: array description: Resolves against the id of a Tariff on /tariffs. items: type: string format: uuid terms_and_conditions: type: string format: uri example: https://char.gy/terms-of-use last_updated: type: string format: date-time Tariff: type: object required: [country_code, party_id, id, currency, elements, last_updated] properties: country_code: type: string example: GB party_id: type: string example: CGY id: type: string format: uuid currency: type: string description: >- GBP, EUR and USD were all observed on GB/CGY tariff records; recorded as observed. example: GBP elements: type: array items: $ref: '#/components/schemas/TariffElement' last_updated: type: string format: date-time TariffElement: type: object required: [price_components] properties: price_components: type: array items: $ref: '#/components/schemas/PriceComponent' restrictions: $ref: '#/components/schemas/TariffRestrictions' PriceComponent: type: object required: [type, price, step_size] properties: type: type: string description: Only ENERGY components were observed — no time or flat fees. enum: [ENERGY] price: type: number description: Price per kWh in the tariff currency. example: 0.325 step_size: type: integer example: 1 TariffRestrictions: type: object properties: start_time: type: string example: '00:00' end_time: type: string example: '07:00' day_of_week: type: array items: type: string enum: [MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY] security: []