{"openapi":"3.1.0","info":{"title":"AthenireCharge Platform API","description":"Unified backend for the AthenireCharge app and website.","version":"1.0.0"},"paths":{"/v1/auth/register":{"post":{"tags":["auth"],"summary":"Register","description":"Create (or return) the platform user for the authenticated caller.\n\nIdempotent: signing in again with the same identity returns the existing\naccount. If no account matches this auth id but one already exists under the\nsame verified email (e.g. a row migrated from Firebase, or the same person\nwho previously signed in another way), that account is adopted and relinked\nto the new auth id — instead of colliding on the unique email.","operationId":"register_v1_auth_register_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/me":{"get":{"tags":["users"],"summary":"Get Me","description":"Who this is, what they hold, and whether they may start a charge.\n\nThe CSMS calls this before energising a cable — it cannot verify a Firebase\nor Supabase token itself, so this doubles as the authentication answer —\nand it used to read only `wallet_balance` and refuse at zero. That was\nright when a wallet was the only way to pay and is wrong now, in both\ndirections:\n\n  * A driver who pays by UPI has no reason to keep a balance, and refusing\n    them at zero blocks somebody who was never going to use the wallet.\n  * A driver who paid by UPI and never actually paid keeps a positive\n    balance and charges forever. The arrears block only ever applied to the\n    RFID path, which is not the path most people use.\n\nSo the verdict is computed here, where every rule that decides it already\nlives, and the CSMS reads a decision rather than a number. One unpaid\ncharge is the exposure and it is deliberate: post-paid means the first\ncharge is on trust, and the second is not.","operationId":"get_me_v1_users_me_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["users"],"summary":"Update Me","operationId":"update_me_v1_users_me_patch","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/vehicles/catalog":{"get":{"tags":["vehicles"],"summary":"Vehicle Catalog","description":"Preset EV models shown on the app's vehicle-selection screen.","operationId":"vehicle_catalog_v1_vehicles_catalog_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/VehicleCatalogItem"},"type":"array","title":"Response Vehicle Catalog V1 Vehicles Catalog Get"}}}}}}},"/v1/vehicles":{"get":{"tags":["vehicles"],"summary":"List Vehicles","operationId":"list_vehicles_v1_vehicles_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VehicleOut"},"title":"Response List Vehicles V1 Vehicles Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["vehicles"],"summary":"Add Vehicle","operationId":"add_vehicle_v1_vehicles_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/vehicles/{vehicle_id}":{"patch":{"tags":["vehicles"],"summary":"Update Vehicle","description":"Edit a saved vehicle, or make it the default.\n\nA garage with no edit is a garage where a typo means delete and start\nagain — and deleting the default silently promotes another car, which is\nnot what somebody fixing a spelling mistake asked for.","operationId":"update_vehicle_v1_vehicles__vehicle_id__patch","parameters":[{"name":"vehicle_id","in":"path","required":true,"schema":{"type":"integer","maximum":2147483647,"title":"Vehicle Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["vehicles"],"summary":"Delete Vehicle","operationId":"delete_vehicle_v1_vehicles__vehicle_id__delete","parameters":[{"name":"vehicle_id","in":"path","required":true,"schema":{"type":"integer","maximum":2147483647,"title":"Vehicle Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/vehicles/{vehicle_id}/insights":{"get":{"tags":["vehicles"],"summary":"Vehicle Insights","description":"Battery health, running cost and displaced emissions for one car.\n\nEverything here refuses rather than extrapolates. A degradation figure from\nthree charges is a rumour with a decimal point, so `battery` is null until\nthere are enough sessions to mean something — and the app shows \"not enough\ncharges yet\", which is true and useful, rather than a number that is not.","operationId":"vehicle_insights_v1_vehicles__vehicle_id__insights_get","parameters":[{"name":"vehicle_id","in":"path","required":true,"schema":{"type":"integer","title":"Vehicle Id"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Vehicle Insights V1 Vehicles  Vehicle Id  Insights Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/vehicles/claims":{"post":{"tags":["vehicles"],"summary":"Request Access","description":"Ask the registered owner of a plate for access to it.\n\nGrants nothing. It creates a question somebody else answers, and until they\ndo, the requester knows only what `describe_conflict` told them: that the\nplate is registered, and roughly to whom.","operationId":"request_access_v1_vehicles_claims_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__v1__vehicles__ClaimRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Request Access V1 Vehicles Claims Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["vehicles"],"summary":"My Claims","description":"Requests waiting on me, and requests I am waiting on.\n\nBoth directions in one call: they are two halves of one situation, and an\napp that has to ask twice will show one of them stale.","operationId":"my_claims_v1_vehicles_claims_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response My Claims V1 Vehicles Claims Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/vehicles/claims/{claim_id}":{"post":{"tags":["vehicles"],"summary":"Decide Claim","description":"The owner's answer. Theirs alone.","operationId":"decide_claim_v1_vehicles_claims__claim_id__post","parameters":[{"name":"claim_id","in":"path","required":true,"schema":{"type":"integer","title":"Claim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimDecision"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Decide Claim V1 Vehicles Claims  Claim Id  Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["vehicles"],"summary":"Withdraw Claim","description":"Take back a request you sent. Idempotent.\n\nSomebody who mistypes a plate should not have to wait a week for their\nmistake to expire, and the owner should not be left holding a decision\nabout a car that has nothing to do with the person asking.","operationId":"withdraw_claim_v1_vehicles_claims__claim_id__delete","parameters":[{"name":"claim_id","in":"path","required":true,"schema":{"type":"integer","title":"Claim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/vehicles/{vehicle_id}/charges":{"get":{"tags":["vehicles"],"summary":"Vehicle Charges","description":"Every charge that went into this car, and who put it there.\n\nThree separate facts per row, because on a shared car they come apart: the\nperson who plugged it in, the wallet the money left, and where it happened.\nA member charging on the family wallet and the same member paying for\nthemselves are different lines in a household conversation, and an app that\ncollapses them cannot settle one.\n\nReadable by the vehicle's owner for every charge, and by anybody else for\ntheir own only — somebody allowed to charge a car once does not thereby get\na log of where its owner drives. The scope lives in the service so a future\ncaller cannot forget it.","operationId":"vehicle_charges_v1_vehicles__vehicle_id__charges_get","parameters":[{"name":"vehicle_id","in":"path","required":true,"schema":{"type":"integer","title":"Vehicle Id"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":90,"title":"Days"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Vehicle Charges V1 Vehicles  Vehicle Id  Charges Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/stations":{"get":{"tags":["stations"],"summary":"List Stations","description":"Geospatial station search — the map + Stations-tab query.\n\nPublic (no auth) so the map can render before sign-in. When `lat`/`lng`\nare supplied, results include `distance_km` and can be radius-filtered and\ndistance-sorted.\n\nResults mix our own stations with partner ones reachable over roaming; the\n`source` field says which, and the app draws and starts them differently.","operationId":"list_stations_v1_stations_get","parameters":[{"name":"lat","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Caller latitude","title":"Lat"},"description":"Caller latitude"},{"name":"lng","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Caller longitude","title":"Lng"},"description":"Caller longitude"},{"name":"radius_km","in":"query","required":false,"schema":{"anyOf":[{"type":"number","exclusiveMinimum":0},{"type":"null"}],"title":"Radius Km"}},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Name/address search","title":"Q"},"description":"Name/address search"},{"name":"connector","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Connector types: ccs, nacs, chademo, type2","title":"Connector"},"description":"Connector types: ccs, nacs, chademo, type2"},{"name":"min_power_kw","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"title":"Min Power Kw"}},{"name":"max_price","in":"query","required":false,"schema":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"title":"Max Price"}},{"name":"available_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Available Only"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","pattern":"^(distance|power)$","default":"distance","title":"Sort"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"include_roaming","in":"query","required":false,"schema":{"type":"boolean","description":"Include partner stations reachable over OCPI roaming","default":true,"title":"Include Roaming"},"description":"Include partner stations reachable over OCPI roaming"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StationSummary"},"title":"Response List Stations V1 Stations Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/stations/{station_id}":{"get":{"tags":["stations"],"summary":"Get Station","operationId":"get_station_v1_stations__station_id__get","parameters":[{"name":"station_id","in":"path","required":true,"schema":{"type":"string","title":"Station Id"}},{"name":"lat","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"}},{"name":"lng","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StationDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/stations/{station_id}/waiting":{"get":{"tags":["stations"],"summary":"Waiting Connectors","description":"Connectors here that are plugged in and not yet charging.\n\nWhat somebody standing in front of one needs. The common case this serves\nis the whole reason it exists: a driver has just seated a cable and is now\nlooking for the button, and an app that can say \"the connector you are\nstanding at is ready — start it\" beats one that makes them find the right\ncharger in a list first.\n\nOpen to anybody at the station rather than only to the car's owner, and\nthat is a deliberate call. It says a connector is occupied and waiting; it\ndoes not say whose car it is, what it is, or anything about the person.\nThat is the same fact the charger's own screen displays to whoever walks\npast, so publishing it to somebody standing there gives nothing away — and\nrestricting it to the owner would break the case where the app has no idea\nwhose car it is, which is every car until its owner starts one charge.","operationId":"waiting_connectors_v1_stations__station_id__waiting_get","parameters":[{"name":"station_id","in":"path","required":true,"schema":{"type":"string","title":"Station Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/places/nearby":{"get":{"tags":["places"],"summary":"Nearby Public Chargers","description":"Public chargers Google knows about near a point.\n\nCoverage the network does not have yet. Without this the map is empty in\nmost of India, which reads as \"this app has no chargers\" rather than the\ntruth, which is that ours are not there *yet* — the worst possible first\nimpression, and an avoidable one.\n\nTiled into a 3×3 grid above a couple of kilometres. Google caps Nearby\nSearch at twenty results per call with no page token, so one call for a\nwhole city returns twenty chargers and silently drops the rest; nine\noverlapping cells return up to a hundred and eighty for the same viewport.\nThe overlap is deliberate — cells offset by half a radius, searched at\nslightly less than half, so nothing falls through the seams.\n\nReturns Google's own shape. The app already parses it.","operationId":"nearby_public_chargers_v1_places_nearby_get","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","maximum":90,"minimum":-90,"title":"Lat"}},{"name":"lng","in":"query","required":true,"schema":{"type":"number","maximum":180,"minimum":-180,"title":"Lng"}},{"name":"radius_km","in":"query","required":false,"schema":{"type":"number","maximum":150,"exclusiveMinimum":0,"default":25.0,"title":"Radius Km"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Nearby Public Chargers V1 Places Nearby Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/places/search":{"get":{"tags":["places"],"summary":"Search Places","description":"Free-text place lookup — the search box and the trip planner's endpoints.\n\nServes both the suggestion list and the single-result geocode, because they\nare one Places call with a different result count and keeping them as two\nendpoints would double the surface for no difference in behaviour.","operationId":"search_places_v1_places_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":120,"title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":10,"minimum":1,"default":6,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Search Places V1 Places Search Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/me/favorites":{"get":{"tags":["favorites"],"summary":"List Favorites","description":"The saved stations themselves, newest first.\n\nReturns full stations rather than ids so the screen can render without a\nsecond round trip per row.","operationId":"list_favorites_v1_users_me_favorites_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StationSummary"},"title":"Response List Favorites V1 Users Me Favorites Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/me/favorites/{station_id}":{"put":{"tags":["favorites"],"summary":"Add Favorite","description":"Save a station. Idempotent — saving twice is the same as saving once.","operationId":"add_favorite_v1_users_me_favorites__station_id__put","parameters":[{"name":"station_id","in":"path","required":true,"schema":{"type":"string","title":"Station Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["favorites"],"summary":"Remove Favorite","description":"Unsave a station. Also idempotent.","operationId":"remove_favorite_v1_users_me_favorites__station_id__delete","parameters":[{"name":"station_id","in":"path","required":true,"schema":{"type":"string","title":"Station Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/me/devices":{"post":{"tags":["notifications"],"summary":"Register Device","description":"Start (or resume) sending notifications to this device.\n\n200 rather than 201 because it is an upsert and the app calls it on every\nlaunch: the same token arriving twice is the normal case, not a conflict.\nA token that was registered to somebody else moves to this account — a\nhanded-down phone should follow whoever last signed in, and continuing to\ntell the previous owner about a stranger's charging session is a privacy\nfailure, not a stale record.","operationId":"register_device_v1_users_me_devices_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/me/devices/{token}":{"delete":{"tags":["notifications"],"summary":"Unregister Device","description":"Stop sending to this device — a sign-out, or notifications switched off.\n\nDeactivated rather than deleted, and idempotent: a token that is not ours,\nor already gone, is still a satisfied request. The app calls this while\nsigning out, and a sign-out that can fail is a sign-out that leaves someone\nreceiving another person's notifications.","operationId":"unregister_device_v1_users_me_devices__token__delete","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/me/notification-preferences":{"get":{"tags":["notifications"],"summary":"Get Notification Preferences","description":"What this person has agreed to. Defaults when they have never changed it.","operationId":"get_notification_preferences_v1_users_me_notification_preferences_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"boolean"},"title":"Response Get Notification Preferences V1 Users Me Notification Preferences Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["notifications"],"summary":"Update Notification Preferences","description":"Change one or more categories. Returns the full, current set.\n\nReturning everything rather than an acknowledgement means the settings\nscreen never has to guess: it renders what the server says is true, so two\ndevices toggling different switches converge instead of each believing its\nown last write.","operationId":"update_notification_preferences_v1_users_me_notification_preferences_put","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferencesIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"boolean"},"title":"Response Update Notification Preferences V1 Users Me Notification Preferences Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/me/devices/test":{"post":{"tags":["notifications"],"summary":"Send Test Notification","description":"Push a test notification to this account's devices.\n\nExists because \"are notifications working?\" is otherwise unanswerable\nwithout waiting for a real charge to finish. Every layer between a driver\nand a notification can fail quietly — the OS permission, the registration,\nthe FCM credential, the channel — and each one produces the identical\nsymptom of nothing happening. This says which.\n\nDeliberately reports the boring cases separately rather than collapsing\nthem into \"failed\":\n\n* `configured: false` — the deployment has no FCM credential. Nothing is\n  wrong with the phone.\n* `devices: 0` — this account has no registered device. Usually the app has\n  not been opened since signing in.\n* `sent: 0` with devices — the token is registered but FCM would not take\n  it. A dead token is retired here, so the next attempt is honest about it.\n\nSafe to call repeatedly. It notifies only the caller's own devices, so the\nworst it can do is buzz your own phone.","operationId":"send_test_notification_v1_users_me_devices_test_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Send Test Notification V1 Users Me Devices Test Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups":{"post":{"tags":["groups"],"summary":"Create Group","description":"Start a family or a team.\n\nThe creator becomes its owner and its first member. `pays_for_members` is\noff until somebody turns it on, so creating a group never silently changes\nwho pays for the creator's own charging.","operationId":"create_group_v1_groups_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Group V1 Groups Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/me":{"get":{"tags":["groups"],"summary":"My Group","description":"The group this driver is in, with everyone's spend.\n\nAnswers `{\"in_group\": false}` rather than 404 for somebody who is in none:\nnot being in a family is an ordinary state, and a screen that has to catch\nan error to render its empty case will eventually render the error.","operationId":"my_group_v1_groups_me_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response My Group V1 Groups Me Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["groups"],"summary":"Update Group","description":"Rename the group, or change whether it pays for its members.","operationId":"update_group_v1_groups_me_patch","parameters":[{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Group V1 Groups Me Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/me/topup":{"post":{"tags":["groups"],"summary":"Top Up Group","description":"Move money from your own wallet into the shared one.\n\nA transfer, not a top-up — and that is the correction, not a limitation.\nCreating money here would be the same hole the personal wallet just had: an\nendpoint that credits a balance because somebody asked. Funding the group\nfrom a personal wallet means every rupee in it entered the platform through\na payment that was actually verified, once, at `/v1/wallet/topup/verify`.\n\nIt also matches how a household reasons about it. Somebody puts their money\ninto the shared pot; the pot does not conjure it.\n\nAny member may contribute. Refusing a contribution because somebody is not\nan admin would be a strange thing for a household wallet to do.","operationId":"top_up_group_v1_groups_me_topup_post","parameters":[{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__v1__groups__TopUpRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Top Up Group V1 Groups Me Topup Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/me/transactions":{"get":{"tags":["groups"],"summary":"Group Statement","description":"The shared wallet's ledger, newest first.\n\nVisible to every member, for the same reason each member's spend is: a\nshared wallet whose statement only one person can read is not shared.","operationId":"group_statement_v1_groups_me_transactions_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Group Statement V1 Groups Me Transactions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/me/invites":{"get":{"tags":["groups"],"summary":"List Invites","description":"Every invite still outstanding, so they can be recognised and revoked.\n\nAn invite nobody can identify is an invite nobody dares revoke, which is\nwhy `label` exists and why this endpoint does: a list of eight-character\ncodes tells the sender nothing about which one they put in which chat.","operationId":"list_invites_v1_groups_me_invites_get","parameters":[{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response List Invites V1 Groups Me Invites Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["groups"],"summary":"Create Invite","description":"A code to hand somebody, over whatever channel this household uses.\n\nA code rather than an email hop: this market invites over WhatsApp, and a\nstring somebody can paste is both simpler and less likely to be lost to a\nspam folder than an address we would first have to verify.\n\nThe invite carries the decisions rather than deferring them. An invitation\nthat only says \"join\" makes the sender do the work twice — send it, wait,\nthen find the new member and set their role and their cap — and in the gap\nbetween joining and remembering, a new driver has no limit at all.","operationId":"create_invite_v1_groups_me_invites_post","parameters":[{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/InviteCreate"},{"type":"null"}],"title":"Body"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Invite V1 Groups Me Invites Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/me/invites/{code}":{"delete":{"tags":["groups"],"summary":"Revoke Invite","description":"Cancel an outstanding invite. Idempotent.","operationId":"revoke_invite_v1_groups_me_invites__code__delete","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}},{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/join":{"post":{"tags":["groups"],"summary":"Join Group","description":"Accept an invitation.\n\nAn invite is single-use. A code that keeps working after somebody has\njoined is a permanent key to the group's money, and the person who pasted\nit into a family chat has no way to take it back.","operationId":"join_group_v1_groups_join_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JoinRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Join Group V1 Groups Join Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/me/members/{member_id}":{"patch":{"tags":["groups"],"summary":"Update Member","description":"Change somebody's role or spending limit.","operationId":"update_member_v1_groups_me_members__member_id__patch","parameters":[{"name":"member_id","in":"path","required":true,"schema":{"type":"integer","title":"Member Id"}},{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Member V1 Groups Me Members  Member Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["groups"],"summary":"Remove Member","description":"Remove somebody, or leave yourself.\n\nMarked rather than deleted. \"Who spent this?\" has to stay answerable after\nsomebody leaves, and a ledger row pointing at a membership that no longer\nexists is a receipt nobody can explain.","operationId":"remove_member_v1_groups_me_members__member_id__delete","parameters":[{"name":"member_id","in":"path","required":true,"schema":{"type":"integer","title":"Member Id"}},{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/me/vehicles":{"get":{"tags":["groups"],"summary":"List Shared Vehicles","description":"The group's pool, and who may charge each car.\n\n`you_may_charge` is computed for the caller rather than left to the app to\nwork out. A driver should be picking from cars that will actually be paid\nfor, not choosing one and finding out at the charger.","operationId":"list_shared_vehicles_v1_groups_me_vehicles_get","parameters":[{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response List Shared Vehicles V1 Groups Me Vehicles Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["groups"],"summary":"Share Vehicle","description":"Put one of your cars into the group's pool.\n\nYours, specifically. Anyone may share a car they own — that is the point of\na household pool and it should not need the owner's involvement — but\nnobody may share somebody else's, which is why ownership is checked here\nrather than assumed from membership.","operationId":"share_vehicle_v1_groups_me_vehicles_post","parameters":[{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareVehicle"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Share Vehicle V1 Groups Me Vehicles Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/me/vehicles/{vehicle_id}":{"patch":{"tags":["groups"],"summary":"Update Shared Vehicle","description":"Change who may charge a shared car.\n\nThe person who shared it, or an owner. A member should not be able to\nrewrite the permissions on somebody else's vehicle, and an owner needs to\nbe able to because otherwise a car shared by someone who has left is stuck.","operationId":"update_shared_vehicle_v1_groups_me_vehicles__vehicle_id__patch","parameters":[{"name":"vehicle_id","in":"path","required":true,"schema":{"type":"integer","title":"Vehicle Id"}},{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareVehicle"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Shared Vehicle V1 Groups Me Vehicles  Vehicle Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["groups"],"summary":"Unshare Vehicle","description":"Take a car back out of the pool. Idempotent.\n\nMarked removed rather than deleted: charges already billed against it have\nto stay explainable, and a statement line pointing at a vehicle the group\nhas never heard of is worse than one pointing at a car that has since left.","operationId":"unshare_vehicle_v1_groups_me_vehicles__vehicle_id__delete","parameters":[{"name":"vehicle_id","in":"path","required":true,"schema":{"type":"integer","title":"Vehicle Id"}},{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/me/statement":{"get":{"tags":["groups"],"summary":"Group Spend Breakdown","description":"This period's spend, broken down by person and by car.\n\nTwo breakdowns because they answer different questions. Per-person settles\n\"who spent this\"; per-vehicle answers \"what does the van cost us a month\",\nwhich per-person cannot, because two drivers sharing one van look like two\ncosts rather than one.","operationId":"group_spend_breakdown_v1_groups_me_statement_get","parameters":[{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Group Spend Breakdown V1 Groups Me Statement Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/mine":{"get":{"tags":["groups"],"summary":"My Groups","description":"Every group this person is in, default first.\n\nSeveral is ordinary — one household and one work team — and the old rule\nthat refused a second join pushed people back to sharing a login, which is\nthe thing shared wallets exist to replace.","operationId":"my_groups_v1_groups_mine_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response My Groups V1 Groups Mine Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/{group_id}/primary":{"post":{"tags":["groups"],"summary":"Set Primary Group","description":"Choose which group your charging bills to by default.\n\nThe car still wins where it can — a vehicle shared into exactly one of your\ngroups bills there regardless — so this decides the cases a car cannot.","operationId":"set_primary_group_v1_groups__group_id__primary_post","parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Set Primary Group V1 Groups  Group Id  Primary Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/{group_id}/leave":{"post":{"tags":["groups"],"summary":"Leave Group","description":"Leave one of your groups. Idempotent.\n\nAn owner cannot simply walk out — the group would be left with a wallet and\nnobody able to move the money in it — but they are no longer stuck either:\n`POST /{id}/transfer` hands it over, and `DELETE /{id}` closes it and\nreturns the balance. Before those two existed this endpoint refused an\nowner and named two operations that did not exist, which is how somebody\nends up trapped in a group they created to try the feature out.","operationId":"leave_group_v1_groups__group_id__leave_post","parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/{group_id}/transfer":{"post":{"tags":["groups"],"summary":"Transfer Ownership","description":"Hand a group to one of its members.\n\nDeliberately a separate, explicit action rather than something an invite\ncan do: a group carries a wallet, and ownership should not change because\na link went to the wrong chat.","operationId":"transfer_ownership_v1_groups__group_id__transfer_post","parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferOwnership"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Transfer Ownership V1 Groups  Group Id  Transfer Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/{group_id}":{"delete":{"tags":["groups"],"summary":"Delete Group","description":"Close a group, returning whatever is left to the owner.\n\nReturning the balance rather than refusing while money is in it. A group\nthat cannot be closed until it is empty is a group somebody has to work out\nhow to empty, and the obvious way — charge until it runs down — is a\nstrange thing to make a person do to delete something.\n\nThe money moves as a ledgered transfer, both sides in one transaction, so\nthe group's balance still equals the sum of its rows at the moment it stops\nbeing used. A refund that only credits one side is how an audit stops\nbalancing.","operationId":"delete_group_v1_groups__group_id__delete","parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Group V1 Groups  Group Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/guest/quote":{"post":{"tags":["guest"],"summary":"Quote","description":"What does this much money buy here?\n\nAnswered before any money is taken, from the tariff in force now. A driver\nhanding over ₹200 at a machine deserves to know what they are getting for\nit, and finding out afterwards is the complaint that makes people stop\nusing prepaid charging.","operationId":"quote_v1_guest_quote_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Quote V1 Guest Quote Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/guest/orders":{"post":{"tags":["guest"],"summary":"Create Order","description":"Begin a guest charge. Takes no money and starts nothing.","operationId":"create_order_v1_guest_orders_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Order V1 Guest Orders Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/guest/verify":{"post":{"tags":["guest"],"summary":"Verify And Start","description":"Confirm the payment and start the charge, capped at what was bought.\n\nThe signature check is the whole security of this endpoint, exactly as it\nis for a wallet top-up — without it, anybody could claim to have paid and\nthe charger would energise a cable for free.","operationId":"verify_and_start_v1_guest_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__v1__guest__VerifyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Verify And Start V1 Guest Verify Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/guest/qr-webhook":{"post":{"tags":["guest"],"summary":"Qr Webhook","description":"The provider telling us a charger's QR was paid.\n\nThe only settlement path this flow has. A walk-up driver never confirms\nanything to us — they scan, pay in their own bank's app, and put the phone\naway — so unlike the app's guest flow there is no client callback to fall\nback on. If this does not fire, somebody has paid for electricity they\nnever received.\n\nUnauthenticated by necessity, so the signature over the raw body is the\nonly thing between this and anybody starting any charger for free. Checked\nbefore the body is parsed.","operationId":"qr_webhook_v1_guest_qr_webhook_post","parameters":[{"name":"x-razorpay-signature","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Razorpay-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Qr Webhook V1 Guest Qr Webhook Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/guest/orders/{order_id}":{"get":{"tags":["guest"],"summary":"Guest Status","description":"Where a guest charge got to.\n\nUnauthenticated by necessity — there is no account — and safe because the\norder id is a long random string that only the person who paid holds. It\nreturns nothing that would matter to somebody who guessed one.","operationId":"guest_status_v1_guest_orders__order_id__get","parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string","title":"Order Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Guest Status V1 Guest Orders  Order Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/referrals":{"get":{"tags":["referrals"],"summary":"My Referrals","description":"This driver's code, and how it is doing.","operationId":"my_referrals_v1_referrals_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response My Referrals V1 Referrals Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/referrals/claim":{"post":{"tags":["referrals"],"summary":"Claim Code","description":"Say who invited you.\n\nAnswers 200 whatever happens, and that is deliberate. An unknown code, your\nown code, or an account that already has a referrer are all ways this can\nlegitimately not apply — and none of them is worth failing on, because the\nperson is joining either way and the worst outcome is that nobody is paid.\nReporting *which* it was would also tell a guesser which codes exist.","operationId":"claim_code_v1_referrals_claim_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__v1__referrals__ClaimRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Claim Code V1 Referrals Claim Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/stations/{station_id}/photos":{"get":{"tags":["photos"],"summary":"Station Photos","description":"Approved photos of a charger, newest first.\n\nPublic, and approved-only. A pending photo is not \"nearly published\" — it\nis a submission a human has not yet agreed to show anyone.","operationId":"station_photos_v1_stations__station_id__photos_get","parameters":[{"name":"station_id","in":"path","required":true,"schema":{"type":"string","title":"Station Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Station Photos V1 Stations  Station Id  Photos Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["photos"],"summary":"Upload Station Photo","description":"Submit a photo of a charger.\n\n202, not 201: the driver's photo has been accepted for review, and saying\n\"created\" would imply it is visible. The response says so in words too,\nbecause a photo that silently does not appear reads as a bug and gets\nuploaded again.","operationId":"upload_station_photo_v1_stations__station_id__photos_post","parameters":[{"name":"station_id","in":"path","required":true,"schema":{"type":"string","title":"Station Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_station_photo_v1_stations__station_id__photos_post"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Upload Station Photo V1 Stations  Station Id  Photos Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/me/photos":{"get":{"tags":["photos"],"summary":"My Photos","description":"This driver's own submissions, whatever their state.\n\nIncluding the rejected ones, with the reason. A photo that vanishes without\nexplanation reads as the app losing it, and the driver uploads it again —\nwhich costs the moderator twice.","operationId":"my_photos_v1_users_me_photos_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response My Photos V1 Users Me Photos Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/me/photos/{photo_id}":{"delete":{"tags":["photos"],"summary":"Withdraw Photo","description":"Take back a photo you submitted.\n\nAllowed at any point, including after approval. Somebody who realises their\nphotograph caught a face or a number plate should not have to write to\nsupport about it.","operationId":"withdraw_photo_v1_users_me_photos__photo_id__delete","parameters":[{"name":"photo_id","in":"path","required":true,"schema":{"type":"integer","title":"Photo Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/photos/pending":{"get":{"tags":["photos"],"summary":"Moderation Queue","description":"Photos waiting for a decision, oldest first.\n\nOldest first because the person who submitted first has been waiting\nlongest, and a queue worked newest-first starves its own backlog.","operationId":"moderation_queue_v1_admin_photos_pending_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Moderation Queue V1 Admin Photos Pending Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/photos/{photo_id}":{"post":{"tags":["photos"],"summary":"Moderate Photo","description":"Approve or reject one photo.\n\nA rejection requires a reason. Not to make the moderator's life harder, but\nbecause the reason is shown to the person who took the photograph — and a\nrejection with no explanation is indistinguishable from the app breaking,\nso they upload it again and the queue never drains.\n\nA rejected photo's bytes are deleted from storage. Keeping them would mean\nthe platform holds an image a human has specifically decided not to publish,\nwhich is the one category of image worth not holding.","operationId":"moderate_photo_v1_admin_photos__photo_id__post","parameters":[{"name":"photo_id","in":"path","required":true,"schema":{"type":"integer","title":"Photo Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModerationDecision"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Moderate Photo V1 Admin Photos  Photo Id  Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/feedback":{"post":{"tags":["feedback"],"summary":"Submit Feedback","description":"Take a driver's feedback.\n\nOpen to signed-out callers on purpose: demanding an account first is how\nyou stop hearing about the bug that stops people making one.\n\n202 rather than 200 — the record is written, the mail has not been sent\nyet, and saying \"accepted\" is the honest description of that.","operationId":"submit_feedback_v1_feedback_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackIn"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Submit Feedback V1 Feedback Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/trips/plan":{"post":{"tags":["trips"],"summary":"Plan Trip","description":"Plan a drive, including where to charge on the way.\n\nOpen, like the rest of discovery. The map, station pages and their reviews\nall work before sign-in because that is what someone evaluating the app\nlooks at first, and planning a drive is the same kind of question — asked,\nin fact, by exactly the driver who has not signed up yet.\n\nIt is also the only honest option today: the app's token store is in-memory\nand station discovery is public, so this was the first endpoint to require\nan account and it failed for *every* user with \"session expired\".\n\nThe cost is real, though — one Routes call and up to 24 Places calls per\nplan — so this needs rate limiting before launch. Left deliberately visible\nrather than papered over with an account check that the client cannot\nsatisfy.","operationId":"plan_trip_v1_trips_plan_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TripPlanIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TripPlanOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/trips/watch":{"post":{"tags":["trips"],"summary":"Watch Trip","description":"Start watching a route for chargers going offline.\n\nReplaces any watch this driver already had. A driver is on one journey at a\ntime, and leaving the previous one live would mean alerts about a route\nthey abandoned an hour ago — which is worse than no alerts, because it\nteaches them to ignore the ones that matter.","operationId":"watch_trip_v1_trips_watch_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TripWatchIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Watch Trip V1 Trips Watch Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["trips"],"summary":"Stop Watching Trip","description":"Stop watching — arrived, or changed plans. Idempotent.","operationId":"stop_watching_trip_v1_trips_watch_delete","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["trips"],"summary":"Current Trip Watch","description":"What this driver is currently being watched for, if anything.\n\nExists so the app can show the state honestly rather than assuming its own\nlast write stuck — a watch expires on its own, and a client that believes\notherwise will claim to be monitoring a journey that ended yesterday.","operationId":"current_trip_watch_v1_trips_watch_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Current Trip Watch V1 Trips Watch Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/wallet":{"get":{"tags":["wallet"],"summary":"Get Wallet","description":"Current wallet balance (source of truth on users.wallet_balance) plus\nthe most recent transactions, newest first.","operationId":"get_wallet_v1_wallet_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/wallet/topup":{"post":{"tags":["wallet"],"summary":"Top Up","description":"Credit a wallet with no payment. Development and tests only.\n\nThis is what the endpoint used to do unconditionally, on a public API: any\naccount could mint itself unlimited credit and spend it on real\nelectricity. It is kept because the test suite and local development need a\nway to put money in a wallet, and it is now behind a setting that is off by\ndefault and named for exactly what it does.\n\nThe real path is `/topup/order` then `/topup/verify`.","operationId":"top_up_v1_wallet_topup_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__schemas__wallet__TopUpRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/wallet/topup/order":{"post":{"tags":["wallet"],"summary":"Start Top Up","description":"Begin a top-up. Credits nothing.\n\nReturns what the app needs to open the provider's own checkout sheet — so\nno card number, UPI PIN or bank credential ever reaches this backend, which\nis most of why using a provider is the right call at all.","operationId":"start_top_up_v1_wallet_topup_order_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Start Top Up V1 Wallet Topup Order Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/wallet/topup/verify":{"post":{"tags":["wallet"],"summary":"Verify Top Up","description":"Confirm a payment the app has just completed, and settle what it was for.\n\nBoth kinds: a wallet top-up credits the balance, a charge paid for directly\nmarks that session paid. The branch is in `_credit`; everything before it —\nthe signature, the row lock, the ownership check, settling exactly once —\nis identical because the problem is identical, and a second copy of it for\ncharge payments would be a second chance to get it wrong.\n\nThe signature is the whole security of this endpoint. Razorpay signs\n`order_id|payment_id` with a secret only they and this process hold, so a\nvalid signature is proof the payment happened for this order. Without that\ncheck, this is the old endpoint with extra steps — a client claiming to\nhave paid.","operationId":"verify_top_up_v1_wallet_topup_verify_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__v1__wallet__VerifyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/wallet/topup/webhook":{"post":{"tags":["wallet"],"summary":"Top Up Webhook","description":"The provider telling us directly that a payment settled.\n\nThe authoritative path, and the reason the flow is safe in the case that\nactually happens: a driver pays, the app is killed by the OS or loses\nsignal before it can confirm, and their money would otherwise be gone. This\ncredits them anyway.\n\nUnauthenticated by necessity — Razorpay has no account here — so the\nsignature over the raw body is the only thing standing between this and\nanybody crediting any wallet. It is checked before the body is parsed.","operationId":"top_up_webhook_v1_wallet_topup_webhook_post","parameters":[{"name":"x-razorpay-signature","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Razorpay-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Top Up Webhook V1 Wallet Topup Webhook Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/wallet/topup/{order_id}":{"get":{"tags":["wallet"],"summary":"Top Up Status","description":"Where a top-up got to.\n\nSo an app that lost the checkout sheet mid-payment can ask rather than\nguess. A driver staring at a wallet that has not moved needs to know\nwhether to pay again, and that is not a question to answer by feel.","operationId":"top_up_status_v1_wallet_topup__order_id__get","parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string","title":"Order Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Top Up Status V1 Wallet Topup  Order Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/wallet/topup/{order_id}/upi-intent":{"post":{"tags":["wallet"],"summary":"Upi Intent For Order","description":"A `upi://` link for an order the app will launch itself.\n\nThis is what lets the payment screen be ours rather than the provider's:\nthe driver taps a tile for an app already on their phone, and this URL\nopens that app with the amount and reference filled in.\n\nThe link is minted by the provider, never assembled here. A hand-built\n`upi://pay?pa=<our vpa>` would collect money perfectly well and collect it\n*outside* the provider's ledger — no webhook, no settlement row, and no\nanswer to \"did my payment arrive\", which is the question the whole recovery\npath exists to answer.\n\nA closed route is not a failed payment. When the account does not have\nserver-side payment creation enabled — a per-merchant permission, not a\nmisconfiguration — this says so plainly so the app can fall back to the\nhosted sheet instead of telling somebody their payment failed.","operationId":"upi_intent_for_order_v1_wallet_topup__order_id__upi_intent_post","parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string","title":"Order Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Upi Intent For Order V1 Wallet Topup  Order Id  Upi Intent Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/wallet/withdraw":{"post":{"tags":["wallet"],"summary":"Withdraw","description":"Send unspent balance back to where it was paid from.\n\nA wallet that money can only enter is not a convenience, it is a deposit\nthe driver cannot recover — and a closed-system instrument stays outside\nRBI authorisation partly because unspent value can be returned on request.\nSo this exists whether or not anybody uses it, and it must keep working.\n\nRefunded against the top-ups that funded the balance, newest first, because\na refund has to go back to a payment the provider can actually reverse. It\nis not a payout to an arbitrary account: the money returns by the route it\narrived, which needs no bank details from the driver and cannot be pointed\nsomewhere else by whoever controls the account today.\n\nThe balance is claimed before any of it is sent, not debited afterwards.\nRead-then-refund-then-debit is a check-then-act on the one endpoint where\nlosing the race means a *second bank transfer* rather than a number that\ndisagrees with the ledger — and the row lock that used to guard it does\nnothing on SQLite, where two concurrent requests for the same ₹1,000 both\nsucceeded. Measured.\n\nSo: take the money out first, under a condition that only one caller can\nsatisfy, then try to return it. Anything that could not be refunded is put\nback, and if none of it could be, the request raises before committing and\nthe claim never happened.","operationId":"withdraw_v1_wallet_withdraw_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WithdrawRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/wallet/payment-options":{"get":{"tags":["wallet"],"summary":"Payment Options","description":"Which wallets this driver could put a charge on.\n\nAssembled server-side because every rule that decides it already lives\nthere — whether a group pays for members, the monthly limit, the balance —\nand an app that re-derives them will eventually derive them differently\nfrom the code that actually bills.\n\nWallets that would refuse are returned rather than filtered out, with the\nreason. An empty family wallet shown greyed and labelled \"This wallet is\nempty\" is a fact somebody can act on; the same wallet simply missing looks\nlike the feature is broken, and sends them hunting for a setting that is\nnot the problem.","operationId":"payment_options_v1_wallet_payment_options_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Payment Options V1 Wallet Payment Options Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sessions":{"get":{"tags":["sessions"],"summary":"List Sessions","description":"The user's completed charging sessions, newest first — the Charging\nHistory screen's source of truth.\n\nBounded. It used to select every session the account had ever had, on every\nopen of the screen: fine at ten, a growing query and a growing response body\nat two thousand, and the drivers who hit that first are the ones who use the\nproduct most. The default ceiling is set well above any real history so\nnothing visible changes today, and `offset` is here so the app can page\nrather than having its tail silently cut off when somebody does exceed it.","operationId":"list_sessions_v1_sessions_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":200,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SessionOut"},"title":"Response List Sessions V1 Sessions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["sessions"],"summary":"Record Session","description":"Record a finished charging session. When it was paid from the wallet,\nthe cost is debited and a matching wallet transaction is written in the\nsame commit, so the wallet and history always agree.\n\nIdempotent on `external_id`: a retry, or the same charge reported by both the\nCSMS and the app, returns the original session rather than debiting twice.\n\nFirst write wins, including its numbers, and that is a decision rather than\nan oversight. The two reporters are independent — the CSMS reads a meter,\nthe app reports what it observed — so a later, different figure is not\nself-evidently a correction. Applying it would let an estimate overwrite a\nmeter reading and move money on the strength of whichever arrived last.\n\nWhat it must not do is disappear. A repeat that disagrees is logged with\nboth figures, so a real correction is something somebody can find and act\non rather than something the system quietly declined to hear.","operationId":"record_session_v1_sessions_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sessions/unpaid":{"get":{"tags":["sessions"],"summary":"Unpaid Charges","description":"Charges this driver has taken and not paid for.\n\nAsked by the app rather than remembered by it, and that is the whole point.\nA charge started from the app is recorded by the app, which knows\nimmediately that a payment is owed — but a charge on real hardware is\nreported by the CSMS when the cable comes out, and the app may not be open,\nmay be on a different phone, or may have been killed by the OS mid-session.\nAn app that only prompts for the charges it happened to record itself will\nmiss exactly the ones that matter most.\n\nSo this is the source of truth for \"do I owe anything\", and it answers the\nsame way whoever did the recording.","operationId":"unpaid_charges_v1_sessions_unpaid_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SessionOut"},"title":"Response Unpaid Charges V1 Sessions Unpaid Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sessions/{session_id}/pay":{"post":{"tags":["sessions"],"summary":"Pay For Charge","description":"An order for a charge the driver chose to pay for directly.\n\nSeparate from recording the session, and deliberately so. The two things\nfail independently — the charge is a fact whether or not a payment provider\nis reachable — and a driver who closes the app between unplugging and\npaying has to be able to come back to it. This is the endpoint the History\nscreen's \"Pay now\" uses, and it is the same one the app calls the moment a\nsession ends.\n\nIdempotent by reuse rather than by refusal: asking twice returns the order\nthat already exists, because a second order for the same charge is a second\nthing somebody can pay, and both would succeed.","operationId":"pay_for_charge_v1_sessions__session_id__pay_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"integer","title":"Session Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayForChargeOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sessions/terms":{"get":{"tags":["sessions"],"summary":"Charging Terms","description":"The billing floor and the free-cancellation window, before anyone pays.\n\nServed rather than hardcoded in the app so the number a driver is shown and\nthe number they are billed come from one place. A minimum disclosed at ₹25\nand applied at ₹30 is worse than no disclosure at all — and on a\ngovernment-adjacent public charger, an undisclosed floor is a complaint\nrather than a margin, which is the whole reason this endpoint exists.\n\nUnauthenticated on purpose: a walk-up driver at a QR code has no account\nyet and still has to be told what they are agreeing to.","operationId":"charging_terms_v1_sessions_terms_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Charging Terms V1 Sessions Terms Get"}}}}}}},"/v1/sessions/{session_id}/remainder":{"get":{"tags":["sessions"],"summary":"Charge Remainder","description":"What a prepaid charge did not use.\n\nA driver who secures ₹935 and uses ₹320 is owed the difference, and the\nreceipt is where they look for it. Served as its own fact rather than\ncomputed in the app, because the two figures behind it — what was\nauthorised and what was billed — are both server-side decisions and an app\nre-deriving them will eventually derive them differently from the code that\nactually took the money.","operationId":"charge_remainder_v1_sessions__session_id__remainder_get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"integer","title":"Session Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemainderOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["sessions"],"summary":"Return Remainder","description":"Return what a prepaid charge did not use, where the driver wants it.\n\nThe money is already in the wallet — prepayment is a top-up, and the charge\nbills from the balance — so \"wallet\" is a no-op that confirms the outcome\nrather than a transfer. That asymmetry is deliberate: the default costs\nnothing and settles instantly, and the alternative is always available.\n\n\"bank\" reverses it through the payment that funded it, which needs no\naccount details from the driver and cannot be redirected by whoever\ncontrols the login today. It also issues the refund voucher that lets the\ntax paid on the advance be adjusted rather than paid on money nobody spent.","operationId":"return_remainder_v1_sessions__session_id__remainder_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"integer","title":"Session Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReturnRemainderIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReturnRemainderOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sessions/deficits":{"get":{"tags":["sessions"],"summary":"My Deficits","description":"What this driver owes, and why.\n\nSeparate from `/unpaid`, and the separation is the point. An unpaid session\nis a payment the driver chose to make afterwards and has not made yet; a\ndeficit is a session that cost more than was secured, which is money the\nplatform is already out of pocket for. They call for different words and\ndifferent buttons, and showing them as one list makes both harder to act on.","operationId":"my_deficits_v1_sessions_deficits_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DeficitOut"},"title":"Response My Deficits V1 Sessions Deficits Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sessions/deficits/settle":{"post":{"tags":["sessions"],"summary":"Settle Deficits","description":"Clear what is owed out of the wallet, as far as it goes.\n\nPartial settlement is the normal case and has to work: somebody with ₹15\nagainst a ₹20 debt clears ₹15 of it, and both the ₹15 taken and the ₹5\nstill owed have to be true afterwards. Refusing unless the balance covers\nthe whole thing would leave a driver unable to make progress on a debt they\nare actively trying to clear.\n\nLocked, because this is a check-then-act on a balance: read what is\navailable, decide how much to apply, write both. Two concurrent calls\nwithout the lock both read the same balance and both spend it.","operationId":"settle_deficits_v1_sessions_deficits_settle_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettleDeficitsOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sessions/intent":{"post":{"tags":["sessions"],"summary":"Remember Intent","description":"Record which car and which payment method, before plugging in.\n\nFor a session the app records itself these travel with it. For a charge on\nreal hardware they cannot: the session is reported by the CSMS when the\ncable comes out, over a service-to-service call that knows nothing about\nwallets — so `pay_with` on that payload was a field nobody ever populated,\nand every OCPP charge went on the driver's own wallet whatever they had\nchosen.\n\nSent here rather than routed through the CSMS on purpose. Payment method\nhas no business in a charging protocol, that path also carries partner and\nroaming traffic, and it would have to survive a charger being offline for\nan hour. The decision is between the driver and the platform; the charger\nis only where it happens.","operationId":"remember_intent_v1_sessions_intent_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntentIn"}}}},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sessions/{session_id}/settle-from-wallet":{"post":{"tags":["sessions"],"summary":"Settle From Wallet","description":"Pay off a charge from a balance after a direct payment did not work.\n\n## Why this exists\n\nA direct payment can fail for reasons that have nothing to do with the\ndriver and everything to do with the moment: a declined card, a UPI app\nthat timed out, a bank having a bad night. The energy is already in the car\nand the charge is already owed, so \"try again later\" is the whole of the\nanswer only if there is nothing else they can do — and there is. Most\ndrivers have a balance, or are in a family that does.\n\nOffering it is also what stops a failed payment turning into a blocked\naccount. An unpaid charge refuses the next one, deliberately; without a way\nto clear it that does not depend on the thing that just broke, a driver\nwhose bank is down cannot charge tomorrow either.\n\n## What it will not do\n\nOverdraw. Unlike the automatic path — which debits after the energy is\ndelivered, where refusing would only make the ledger disagree with reality\n— nothing is being delivered here. The debt already exists and is already\nrecorded; moving it from \"unpaid charge\" to \"negative balance\" changes\nwhich rule blocks them, not whether they owe it. So a wallet that cannot\ncover this says so, and \"due\" keeps meaning something a driver can act on.","operationId":"settle_from_wallet_v1_sessions__session_id__settle_from_wallet_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"integer","title":"Session Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettleIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/chargers":{"get":{"tags":["chargers"],"summary":"List Chargers","description":"The chargers this owner has registered, newest first.","operationId":"list_chargers_v1_chargers_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChargerOut"},"title":"Response List Chargers V1 Chargers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["chargers"],"summary":"Register Charger","description":"Register an OCPP charger to this account. Registering a charger makes\nthe account a host (so it gets the owner experience).","operationId":"register_charger_v1_chargers_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__schemas__charger__ChargerCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChargerOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/chargers/{charger_id}":{"patch":{"tags":["chargers"],"summary":"Update Charger","description":"Attach this charger to one of the owner's stations, or detach it (null).\n\nUntil a charger carries a `station_id`, `GET /v1/stations/{id}` cannot tell\nthe app which charge point that station is, so the driver flow silently\nfalls back to the CSMS's default charger.","operationId":"update_charger_v1_chargers__charger_id__patch","parameters":[{"name":"charger_id","in":"path","required":true,"schema":{"type":"integer","maximum":2147483647,"title":"Charger Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChargerUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChargerOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["chargers"],"summary":"Delete Charger","operationId":"delete_charger_v1_chargers__charger_id__delete","parameters":[{"name":"charger_id","in":"path","required":true,"schema":{"type":"integer","maximum":2147483647,"title":"Charger Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/sessions":{"get":{"tags":["host"],"summary":"Host Sessions","description":"Every charge delivered by this host's chargers, newest first.\n\n`GET /v1/sessions` could not answer this: it scopes to\n`ChargingSessionRecord.user_id`, which is the *driver's* own history. An\noperator asking \"what did my site do yesterday\" was querying the wrong\ncolumn entirely, and there was no endpoint that asked the right one.\n\nScoped exactly as `/overview` is, and for the same reason — sessions reach\nus under two conventions, the CSMS writing `station_id` as the charger's\nOCPP identity and the app writing the station's slug. Matching only one of\nthem hides half the operator's revenue, which is a bug this codebase has\nalready had once.\n\nBounded by default. A busy site accumulates sessions faster than anything\nelse in the schema, and an unbounded list is a query that is fine in\ntesting and a timeout in the third month.","operationId":"host_sessions_v1_host_sessions_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HostSessionOut"},"title":"Response Host Sessions V1 Host Sessions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/overview":{"get":{"tags":["host"],"summary":"Host Overview","description":"At-a-glance analytics for the owner: units delivered, sessions and\ndistinct drivers — today and all-time — across their chargers.","operationId":"host_overview_v1_host_overview_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostOverviewOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/stations":{"get":{"tags":["host"],"summary":"My Stations","description":"The stations this host owns, with their connectors and chargers.","operationId":"my_stations_v1_host_stations_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HostStationOut"},"title":"Response My Stations V1 Host Stations Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["host"],"summary":"Create Station","description":"Create a station the host owns, with N chargers (each an OCPP charge\npoint + a connector). Registering a station makes the account a host.","operationId":"create_station_v1_host_stations_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostStationCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostStationOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/reset":{"post":{"tags":["host"],"summary":"Host Reset","description":"Reboot the charger — Soft (graceful) or Hard (power-cycle).","operationId":"host_reset_v1_host_chargers__ocpp_identity__reset_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/unlock":{"post":{"tags":["host"],"summary":"Host Unlock","description":"Release a stuck cable/plug on a connector.","operationId":"host_unlock_v1_host_chargers__ocpp_identity__unlock_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnlockIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/availability":{"post":{"tags":["host"],"summary":"Host Availability","description":"Take a connector/charger Operative or Inoperative (maintenance).","operationId":"host_availability_v1_host_chargers__ocpp_identity__availability_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvailabilityIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/trigger":{"post":{"tags":["host"],"summary":"Host Trigger","description":"Ask the charger to (re)send a message now — e.g. StatusNotification/MeterValues.","operationId":"host_trigger_v1_host_chargers__ocpp_identity__trigger_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/charging-profile":{"post":{"tags":["host"],"summary":"Host Charging Profile","description":"Cap a connector's power (smart charging).","operationId":"host_charging_profile_v1_host_chargers__ocpp_identity__charging_profile_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChargingProfileIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/command":{"post":{"tags":["host"],"summary":"Host Command","description":"Escape hatch — relay any CSMS→charger command for a charger you own.","operationId":"host_command_v1_host_chargers__ocpp_identity__command_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/configuration":{"get":{"tags":["host"],"summary":"Host Get Configuration","description":"Read the charger's OCPP 1.6 configuration keys (GetConfiguration).\n`keys` is an optional comma-separated filter.","operationId":"host_get_configuration_v1_host_chargers__ocpp_identity__configuration_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"keys","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Keys"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["host"],"summary":"Host Change Configuration","description":"Set one OCPP 1.6 configuration key (ChangeConfiguration) — e.g.\nHeartbeatInterval, MeterValueSampleInterval.","operationId":"host_change_configuration_v1_host_chargers__ocpp_identity__configuration_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeConfigIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/firmware":{"post":{"tags":["host"],"summary":"Host Update Firmware","description":"Push an OTA firmware update (UpdateFirmware). Progress shows on the\ncharger's status (FirmwareStatusNotification).","operationId":"host_update_firmware_v1_host_chargers__ocpp_identity__firmware_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFirmwareIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/diagnostics":{"post":{"tags":["host"],"summary":"Host Get Diagnostics","description":"Ask the charger to upload its diagnostics/log file (GetDiagnostics).","operationId":"host_get_diagnostics_v1_host_chargers__ocpp_identity__diagnostics_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiagnosticsIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/log":{"post":{"tags":["host"],"summary":"Host Get Log","description":"Pull a log file from the charger (GetLog).","operationId":"host_get_log_v1_host_chargers__ocpp_identity__log_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetLogIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/display-message":{"post":{"tags":["host"],"summary":"Host Set Display Message","description":"Show custom text on the charger's screen (SetDisplayMessage, 2.0.1).","operationId":"host_set_display_message_v1_host_chargers__ocpp_identity__display_message_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisplayMessageIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/display-messages":{"get":{"tags":["host"],"summary":"Host Get Display Messages","description":"List messages configured on the charger's screen (GetDisplayMessages).","operationId":"host_get_display_messages_v1_host_chargers__ocpp_identity__display_messages_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/monitoring":{"post":{"tags":["host"],"summary":"Host Set Monitoring","description":"Alert when a variable crosses a threshold (SetVariableMonitoring) — e.g.\ntemperature above 60 °C or voltage below 200 V.","operationId":"host_set_monitoring_v1_host_chargers__ocpp_identity__monitoring_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetMonitoringIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["host"],"summary":"Host Monitoring Report","description":"The monitors currently set on the charger (GetMonitoringReport).\n\nThe counterpart to POST .../monitoring: it is what makes the ids needed to\nclear a monitor discoverable.","operationId":"host_monitoring_report_v1_host_chargers__ocpp_identity__monitoring_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/monitoring-base":{"post":{"tags":["host"],"summary":"Host Set Monitoring Base","description":"Set the monitoring base (SetMonitoringBase).","operationId":"host_set_monitoring_base_v1_host_chargers__ocpp_identity__monitoring_base_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitoringBaseIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/alerts":{"get":{"tags":["host"],"summary":"Host Alerts","description":"Recent monitoring alerts the charger pushed (NotifyEvent).","operationId":"host_alerts_v1_host_chargers__ocpp_identity__alerts_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/data-transfer":{"post":{"tags":["host"],"summary":"Host Data Transfer","description":"Send a free-form vendor DataTransfer to the charger (maker-specific\ncommands / data — extra sensors, custom features).","operationId":"host_data_transfer_v1_host_chargers__ocpp_identity__data_transfer_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataTransferIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/smart-charging":{"post":{"tags":["host"],"summary":"Host Smart Charging","description":"Set/clear a power-management policy: cap kW, a recurring daily window, or\na per-phase current limit. Persisted (so it's re-applied on reconnect) AND\npushed to the charger now via the CSMS.","operationId":"host_smart_charging_v1_host_chargers__ocpp_identity__smart_charging_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmartChargingIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["host"],"summary":"Host Get Smart Charging","description":"The saved policy plus the charger's live composite schedule (if online).","operationId":"host_get_smart_charging_v1_host_chargers__ocpp_identity__smart_charging_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"connector_id","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Connector Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/reservations":{"get":{"tags":["host"],"summary":"Host Reservations","description":"Active reservations on a charger the owner owns (lapsed ones retired).","operationId":"host_reservations_v1_host_chargers__ocpp_identity__reservations_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/auth-tokens":{"get":{"tags":["host"],"summary":"Host List Tokens","description":"The RFID cards / idTags authorized on a charger the owner owns.","operationId":"host_list_tokens_v1_host_chargers__ocpp_identity__auth_tokens_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["host"],"summary":"Host Add Token","description":"Authorize a new RFID card / idTag on the charger's whitelist.","operationId":"host_add_token_v1_host_chargers__ocpp_identity__auth_tokens_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokenIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/auth-tokens/{token_id}":{"delete":{"tags":["host"],"summary":"Host Remove Token","description":"Remove an RFID card / idTag from the whitelist.","operationId":"host_remove_token_v1_host_chargers__ocpp_identity__auth_tokens__token_id__delete","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"token_id","in":"path","required":true,"schema":{"type":"string","title":"Token Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/local-list/sync":{"post":{"tags":["host"],"summary":"Host Sync Local List","description":"Push the current whitelist to the charger as a full local auth list\n(SendLocalList), bumping the version. This is what enables offline auth.","operationId":"host_sync_local_list_v1_host_chargers__ocpp_identity__local_list_sync_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/local-list/version":{"get":{"tags":["host"],"summary":"Host Local List Version","description":"The charger's current local-list version (live, via the CSMS) plus the\nversion the platform last pushed.","operationId":"host_local_list_version_v1_host_chargers__ocpp_identity__local_list_version_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/clear-cache":{"post":{"tags":["host"],"summary":"Host Clear Cache","description":"Clear the charger's authorization cache (ClearCache).","operationId":"host_clear_cache_v1_host_chargers__ocpp_identity__clear_cache_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/variables":{"post":{"tags":["host"],"summary":"Host Get Variables","description":"Read device-model variables (GetVariables, 2.0.1).","operationId":"host_get_variables_v1_host_chargers__ocpp_identity__variables_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetVariablesIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["host"],"summary":"Host Set Variables","description":"Write device-model variables (SetVariables, 2.0.1).","operationId":"host_set_variables_v1_host_chargers__ocpp_identity__variables_patch","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetVariablesIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/base-report":{"post":{"tags":["host"],"summary":"Host Get Base Report","description":"Ask the charger to send its full inventory (GetBaseReport, 2.0.1).\n\nThe charger answers asynchronously over NotifyReport, so read the result from\n`GET .../base-report` once it has arrived.","operationId":"host_get_base_report_v1_host_chargers__ocpp_identity__base_report_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BaseReportIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["host"],"summary":"Host Charger Report","description":"The device-model inventory the charger has reported so far (NotifyReport).","operationId":"host_charger_report_v1_host_chargers__ocpp_identity__base_report_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/display-messages/{message_id}":{"delete":{"tags":["host"],"summary":"Host Clear Display Message","description":"Remove one message from the charger's screen (ClearDisplayMessage).\n\nWithout this an owner could put text on a charger and never take it off.","operationId":"host_clear_display_message_v1_host_chargers__ocpp_identity__display_messages__message_id__delete","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"message_id","in":"path","required":true,"schema":{"type":"integer","title":"Message Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/monitoring/clear":{"post":{"tags":["host"],"summary":"Host Clear Monitoring","description":"Remove monitors by id (ClearVariableMonitoring).","operationId":"host_clear_monitoring_v1_host_chargers__ocpp_identity__monitoring_clear_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClearMonitoringIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/data-transfers":{"get":{"tags":["host"],"summary":"Host Data Transfers","description":"Vendor-specific DataTransfer messages the charger has sent us.\n\nThe send direction already existed; this is the read side, so an owner can\nactually see what their hardware reported.","operationId":"host_data_transfers_v1_host_chargers__ocpp_identity__data_transfers_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/faults":{"get":{"tags":["host"],"summary":"Host Faults","description":"Why this charger's connectors went down — not just that they did.\n\nOCPP carries the diagnosis in StatusNotification's `errorCode`,\n`vendorErrorCode` and `info`. The CSMS used to discard all three, so an\nowner saw \"Faulted\" and had to call an engineer to find out what kind.\n`history=true` returns resolved faults too, which is what makes \"this\nconnector fails every Tuesday\" visible.","operationId":"host_faults_v1_host_chargers__ocpp_identity__faults_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"history","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"History"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/security-events":{"get":{"tags":["host"],"summary":"Host Security Events","description":"Security events the charger reported: failed logins, tamper detection,\nfirmware whose signature did not verify, unexpected reboots.","operationId":"host_security_events_v1_host_chargers__ocpp_identity__security_events_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/rotate-credentials":{"post":{"tags":["host"],"summary":"Host Rotate Credentials","description":"Give this charger its own WebSocket password instead of the fleet-wide\nshared secret.\n\nThe CSMS pushes the new secret over the charger's existing authenticated\nlink before it starts expecting it, so a charger that fails to apply the\nchange is not locked out. The password is returned **once** — the CSMS\nstores only a hash and cannot show it again.","operationId":"host_rotate_credentials_v1_host_chargers__ocpp_identity__rotate_credentials_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/queued-commands":{"get":{"tags":["host"],"summary":"Host Queued Commands","description":"Commands parked because the charger was offline when they were issued.\n\nThey are delivered automatically on its next reconnect; this is how an owner\nsees that a start they requested is waiting rather than lost.","operationId":"host_queued_commands_v1_host_chargers__ocpp_identity__queued_commands_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/queued-commands/cancel":{"post":{"tags":["host"],"summary":"Host Cancel Queued Command","description":"Drop a parked command the owner no longer wants delivered.","operationId":"host_cancel_queued_command_v1_host_chargers__ocpp_identity__queued_commands_cancel_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueuedCommandIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/ev-charging-needs":{"get":{"tags":["host"],"summary":"Host Ev Charging Needs","description":"What the vehicle told the charger it needs (ISO 15118): departure time,\nenergy required, current limits, and the schedule it proposed.","operationId":"host_ev_charging_needs_v1_host_chargers__ocpp_identity__ev_charging_needs_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/csms-reservations":{"get":{"tags":["host"],"summary":"Host Csms Reservations","description":"The holds the CSMS is enforcing on this charger.\n\nDistinct from `/v1/reservations`, which is the platform's own booking\nrecord: this is what the charging network will actually refuse a walk-up\ndriver on, so a mismatch between the two is worth being able to see.","operationId":"host_csms_reservations_v1_host_chargers__ocpp_identity__csms_reservations_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"active_only","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Active Only"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/csms/delivery-health":{"get":{"tags":["host"],"summary":"Host Delivery Health","description":"Sessions the charging network still owes this backend, and any it could\nnot deliver.\n\nA non-zero `dead` count is completed charging that was never recorded — real\nmoney missing from the books — so it belongs somewhere an operator looks\nrather than only in the CSMS's logs.","operationId":"host_delivery_health_v1_host_csms_delivery_health_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/csms/delivery-health/retry":{"post":{"tags":["host"],"summary":"Host Retry Deliveries","description":"Replay dead-lettered session deliveries once whatever broke is fixed.\n\nSafe to repeat: the CSMS keys each delivery on the session's `external_id`,\nand both session endpoints return the original record for an id they have\nalready seen, so a replay cannot double-bill a driver.","operationId":"host_retry_deliveries_v1_host_csms_delivery_health_retry_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetryDeliveriesIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/sites":{"get":{"tags":["host"],"summary":"Host Sites","description":"The electrical sites this host runs.","operationId":"host_sites_v1_host_sites_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["host"],"summary":"Host Upsert Site","description":"Create or update a site and its supply limit.\n\nThe circuit limit is the number that matters: chargers behind one connection\nroutinely add up to several times what it can carry, and this is what lets\nthe CSMS divide it instead of tripping the main breaker.","operationId":"host_upsert_site_v1_host_sites_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/sites/telemetry":{"post":{"tags":["host"],"summary":"Host Site Telemetry","description":"Push a reading from the site's meter or inverter.\n\nThis is what makes load management aware of reality rather than a static\nconfiguration: the building's actual draw, current solar output, and whether\nthe site has switched to its generator.","operationId":"host_site_telemetry_v1_host_sites_telemetry_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelemetryIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/sites/{site_id}/plan":{"get":{"tags":["host"],"summary":"Host Site Plan","description":"What each connector would be limited to, and the arithmetic behind it.\n\nThe dry run an owner reads when a driver complains a car is charging slowly:\nit shows the circuit limit, what came off for the building, what solar added\nand what the generator capped.","operationId":"host_site_plan_v1_host_sites__site_id__plan_get","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/sites/{site_id}/apply-plan":{"post":{"tags":["host"],"summary":"Host Apply Site Plan","operationId":"host_apply_site_plan_v1_host_sites__site_id__apply_plan_post","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/tariffs":{"get":{"tags":["host"],"summary":"Host Tariffs","operationId":"host_tariffs_v1_host_tariffs_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["host"],"summary":"Host Upsert Tariff","description":"Create or update a price list.\n\nTime-of-day slabs may wrap past midnight — which is how off-peak night rates\nare written — and are evaluated in the site's own timezone.\n\nRestricting one to certain days needs care, because a band is matched\nagainst a single instant and `days` is checked against *that instant's*\nweekday, not the day the band started on. So a night rate written as\n22:00–06:00 on Friday covers Friday 22:00–23:59 and Friday 00:00–05:59 —\nthe second of which is Thursday night to everyone who is not a computer —\nand does not cover Saturday 01:00 at all.\n\nWrite the two halves separately:\n\n    {\"start\": \"22:00\", \"end\": \"00:00\", \"days\": [4], ...}   Fri → midnight\n    {\"start\": \"00:00\", \"end\": \"06:00\", \"days\": [5], ...}   Sat 00:00–06:00\n\nA band with no `days` needs none of this: 22:00–06:00 then covers every\nnight straight through.","operationId":"host_upsert_tariff_v1_host_tariffs_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/tariffs/quote":{"post":{"tags":["host"],"summary":"Host Quote Tariff","description":"Price a hypothetical session.\n\nTwo uses: showing a driver a rate before they plug in, and letting whoever\nwrote the tariff check it does what they meant — a slab boundary in the\nwrong timezone is otherwise discovered on a customer's bill.","operationId":"host_quote_tariff_v1_host_tariffs_quote_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/assign":{"post":{"tags":["host"],"summary":"Host Assign Charger","description":"Attach a charger to one of this host's sites, and record its rating.\n\nThe nameplate rating matters to load management: without it the CSMS has to\nguess, and a guess that is too high hands a connector capacity it cannot use\nwhile another goes short.","operationId":"host_assign_charger_v1_host_chargers__ocpp_identity__assign_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignChargerIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/health/fleet":{"get":{"tags":["host"],"summary":"Host Fleet Health","description":"How the host's chargers are actually performing.\n\nReported as two numbers side by side on purpose. Uptime says a charger was\nreachable; first-attempt success rate says a driver who walked up to it got\na charge. Networks routinely report 99% on the first while the second is\nnearer 70%, and the gap is where the complaints come from.","operationId":"host_fleet_health_v1_host_health_fleet_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Hours"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/health":{"get":{"tags":["host"],"summary":"Host Charger Health","description":"Uptime, success rate and open anomalies for one charger.","operationId":"host_charger_health_v1_host_chargers__ocpp_identity__health_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Hours"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/reports/{report_id}/evidence":{"get":{"tags":["host"],"summary":"Host Report Evidence","description":"The OCPP exchange behind one driver's problem report.\n\nThis is the whole point of recording what a report was about. Before it,\nan operator read \"faulted at Bay 2\" and had two choices: ask the driver\nwhat time it was and go looking by hand, or close it unread. Most were\nclosed unread, which is how a reliability signal turns into noise.\n\nReturns frames for the exact session when the driver had one, and the\ncharger's recent traffic when they did not — because \"it would not start\"\nis the report most worth acting on and is precisely the one with no\nsession behind it.\n\n`evidence` says which of those you are looking at, so nobody mistakes a\ncharger's general traffic for the exchange that failed.","operationId":"host_report_evidence_v1_host_reports__report_id__evidence_get","parameters":[{"name":"report_id","in":"path","required":true,"schema":{"type":"integer","title":"Report Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":400,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Host Report Evidence V1 Host Reports  Report Id  Evidence Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/frames":{"get":{"tags":["host"],"summary":"Host Frames","description":"The raw OCPP conversation with this charger.\n\nKept verbatim because the useful question after a field failure (\"what\nexactly did it send, and what did we say back?\") is only formulated\nafterwards, by which time an aggregate has thrown the answer away.","operationId":"host_frames_v1_host_chargers__ocpp_identity__frames_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Limit"}},{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/replay":{"post":{"tags":["host"],"summary":"Host Replay","description":"A failed session's conversation, as a re-runnable script.\n\nEach step carries the delay that preceded it and the answer the CSMS gave at\nthe time, so a fix can be verified against the real sequence rather than a\nreconstruction of it.","operationId":"host_replay_v1_host_chargers__ocpp_identity__replay_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplayIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/swaps":{"get":{"tags":["host"],"summary":"Host Swaps","description":"Battery exchanges at a swap station — the two- and three-wheeler flow,\nwhich is not a charging session and does not appear in session history.","operationId":"host_swaps_v1_host_chargers__ocpp_identity__swaps_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/payments/intent":{"post":{"tags":["host"],"summary":"Host Create Payment","description":"Put a UPI QR on the charger's screen for a walk-up driver.\n\nThe charge does not start here — it starts when the payment settles. Every\nCSMS that answers the UPI mandate with \"install our app\" is asking someone\nwho wants ₹200 of electricity to create an account first.","operationId":"host_create_payment_v1_host_chargers__ocpp_identity__payments_intent_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentIntentIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/payments":{"get":{"tags":["host"],"summary":"Host Payments","operationId":"host_payments_v1_host_chargers__ocpp_identity__payments_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/ocpi/parties":{"get":{"tags":["host"],"summary":"Host Ocpi Parties","description":"Roaming peers this network exchanges with.","operationId":"host_ocpi_parties_v1_host_ocpi_parties_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["host"],"summary":"Host Register Ocpi Party","description":"Register a roaming partner and mint the token that starts their handshake.\n\nIndia has no Hubject-style clearing house, so peering is direct and\nbilateral. The returned `token_a` is shown once and is deliberately\nshort-lived: the partner spends it on the credentials handshake, which\nissues the durable token they use from then on.","operationId":"host_register_ocpi_party_v1_host_ocpi_parties_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcpiPartyIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/ocpi/readiness":{"get":{"tags":["host"],"summary":"Host Ocpi Readiness","description":"What a roaming partner would actually see of this network.\n\n`locations.withheld` is the one to read: stations that charge perfectly but\nthat no partner's app can display, because the site has no coordinates.","operationId":"host_ocpi_readiness_v1_host_ocpi_readiness_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/ocpi/cdrs/unsettled":{"get":{"tags":["host"],"summary":"Host Unsettled Cdrs","description":"Charge Detail Records a partner has not collected — energy delivered and\nnever invoiced, which nothing else in the system will notice.","operationId":"host_unsettled_cdrs_v1_host_ocpi_cdrs_unsettled_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/alerts":{"get":{"tags":["host"],"summary":"Host Alerts","description":"Everything wrong with this host's chargers.\n\nOpen by default: a list that includes months of resolved incidents is one\nnobody reads.","operationId":"host_alerts_v1_host_alerts_get","parameters":[{"name":"open_only","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Open Only"}},{"name":"severity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Severity"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/alerts/ack":{"post":{"tags":["host"],"summary":"Host Ack Alert","description":"Mark an alert seen, or fixed.","operationId":"host_ack_alert_v1_host_alerts_ack_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertAckIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/maintenance":{"get":{"tags":["host"],"summary":"Host Maintenance","description":"Which of this host's chargers need attention, worst first.\n\nScored by the CSMS from the attempt, fault and connectivity history it has\nbeen collecting. The findings carry the evidence, so an engineer is told\nwhat to expect rather than just where to go.","operationId":"host_maintenance_v1_host_maintenance_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":7,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/maintenance":{"get":{"tags":["host"],"summary":"Host Charger Maintenance","description":"One charger's health score and the evidence behind each finding.","operationId":"host_charger_maintenance_v1_host_chargers__ocpp_identity__maintenance_get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":7,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/devices":{"post":{"tags":["host"],"summary":"Host Register Device","description":"Register a device for push notifications.\n\nStored now and used once Firebase is wired — the pipeline already decides\nwho to notify and when, so this is the missing \"where\".","operationId":"host_register_device_v1_host_devices_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceTokenIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/devices/{token}":{"delete":{"tags":["host"],"summary":"Host Unregister Device","description":"Stop pushing to a device — a sign-out, or a phone that changed hands.","operationId":"host_unregister_device_v1_host_devices__token__delete","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/payouts":{"get":{"tags":["host"],"summary":"Host Payouts","description":"This host's settlement statements, newest first.","operationId":"host_payouts_v1_host_payouts_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/payouts/preview":{"get":{"tags":["host"],"summary":"Host Payout Preview","description":"What a period settles to, without closing it.\n\nRead-only on purpose — a host watching the current month's running total\nshould not thereby close it.","operationId":"host_payout_preview_v1_host_payouts_preview_get","parameters":[{"name":"period","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Period"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/payouts/close":{"post":{"tags":["host"],"summary":"Host Close Period","description":"Turn a finished period into a statement.\n\nClosing is idempotent and one-way: a statement that changes after it has\nbeen sent is worse than no statement, so a session arriving late lands in\nthe next period rather than reopening this one.","operationId":"host_close_period_v1_host_payouts_close_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClosePeriodIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/payouts/paid":{"post":{"tags":["host"],"summary":"Host Mark Paid","description":"Record that money actually reached a host. Admin only — a host marking\ntheir own statement paid would be marking their own homework.","operationId":"host_mark_paid_v1_host_payouts_paid_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkPaidIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/sites/{site_id}/demand":{"get":{"tags":["host"],"summary":"Host Site Demand","description":"Peak demand for a site, and what managing it is worth.\n\nAn Indian commercial connection bills on peak kVA as well as kWh, and one\nfifteen-minute spike sets the charge for the whole month — which is\ninvisible to a load manager that only guards the breaker.","operationId":"host_site_demand_v1_host_sites__site_id__demand_get","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}},{"name":"periods","in":"query","required":false,"schema":{"type":"integer","default":12,"title":"Periods"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/battery/packs":{"get":{"tags":["host"],"summary":"Host Battery Packs","description":"Battery packs at this host's swap stations, worst health first.\n\nFor a swap operator the packs are the capital asset: one that has lost a\nfifth of its capacity takes the same handling and delivers a fifth less.","operationId":"host_battery_packs_v1_host_battery_packs_get","parameters":[{"name":"station","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Station"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/audit":{"get":{"tags":["host"],"summary":"Host Audit","description":"Who drove this host's chargers, and what happened.\n\nScoped to chargers the caller owns — an audit trail that showed another\noperator's commands would be its own disclosure problem.","operationId":"host_audit_v1_host_audit_get","parameters":[{"name":"identity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Identity"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/compliance":{"post":{"tags":["host"],"summary":"Host Set Compliance","description":"Record a charger's Indian type approval.\n\nA public charger without BIS/ARAI certification cannot legally be operated,\nso keeping it against the unit turns an audit into a query.","operationId":"host_set_compliance_v1_host_chargers__ocpp_identity__compliance_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComplianceIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/compliance":{"get":{"tags":["host"],"summary":"Host Compliance","description":"Which of this host's chargers are certified, and which lapse soon.\n\nAn expiring certificate is a charger that has to come off the network on a\ndate somebody needs to know in advance.","operationId":"host_compliance_v1_host_compliance_get","parameters":[{"name":"days_ahead","in":"query","required":false,"schema":{"type":"integer","default":90,"title":"Days Ahead"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/reliability":{"get":{"tags":["host"],"summary":"Host Reliability","description":"What drivers actually experienced, next to what the dashboard reports.\n\nThe gap between the two is the number worth acting on: a charger reachable\n99% of the time where 70% of attempts succeed is online and useless, and\nnothing on an uptime graph shows it.","operationId":"host_reliability_v1_host_reliability_get","parameters":[{"name":"ocpp_identity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocpp Identity"}},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Hours"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/reliability/recoveries":{"get":{"tags":["host"],"summary":"Host Recoveries","description":"Faults that were fixed remotely, and the ones that kept coming back.\n\nWorth showing a host because a charger quietly self-healing three times a\nday looks perfectly healthy on every other view.","operationId":"host_recoveries_v1_host_reliability_recoveries_get","parameters":[{"name":"ocpp_identity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocpp Identity"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/recover":{"post":{"tags":["host"],"summary":"Host Recover","description":"Try to clear a fault remotely rather than sending somebody out.","operationId":"host_recover_v1_host_chargers__ocpp_identity__recover_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"connector_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Connector Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/queue/{ocpp_identity}":{"get":{"tags":["host"],"summary":"Host Queue","description":"Who is waiting for this charger, in order.","operationId":"host_queue_v1_host_queue__ocpp_identity__get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/v2g/dispatches":{"get":{"tags":["host"],"summary":"Host V2G Dispatches","operationId":"host_v2g_dispatches_v1_host_v2g_dispatches_get","parameters":[{"name":"ocpp_identity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocpp Identity"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/v2g/dispatch":{"post":{"tags":["host"],"summary":"Host V2G Dispatch","description":"Ask a plugged-in vehicle to export.\n\nNever takes a car below its floor, so a driver who lends energy still\nleaves with enough to get home.","operationId":"host_v2g_dispatch_v1_host_v2g_dispatch_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2GDispatchIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/v2g/dispatch/{dispatch_id}/stop":{"post":{"tags":["host"],"summary":"Host V2G Stop","operationId":"host_v2g_stop_v1_host_v2g_dispatch__dispatch_id__stop_post","parameters":[{"name":"dispatch_id","in":"path","required":true,"schema":{"type":"integer","title":"Dispatch Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/chargers/{ocpp_identity}/v2g-capability":{"post":{"tags":["host"],"summary":"Host V2G Capability","description":"Mark a charger as bidirectional, for hardware that does not advertise it.","operationId":"host_v2g_capability_v1_host_chargers__ocpp_identity__v2g_capability_post","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2GCapabilityIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/v2g/capacity/{site_id}":{"get":{"tags":["host"],"summary":"Host V2G Capacity","description":"How much export this site could dispatch right now.\n\nCounts only vehicles plugged in, bidirectional and above their floor — the\nnumber a grid operator would actually buy against.","operationId":"host_v2g_capacity_v1_host_v2g_capacity__site_id__get","parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","title":"Site Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/pnc/contracts":{"get":{"tags":["host"],"summary":"Host Contracts","description":"The Plug & Charge contracts this host registered.\n\nFiltered here rather than by the CSMS because the two disagree about what\nidentifies a contract's owner: the control API filters on `account_ref`,\nwhich names the *driver* being billed, while the host who registered it is\nrecorded in the `org_id` stamped below. So over-fetch and trim, the same\nshape as the reliability and V2G relays above.","operationId":"host_contracts_v1_host_pnc_contracts_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["host"],"summary":"Host Install Contract","description":"Bind a driver's contract to the account that pays for it.\n\nWithout the binding the handshake succeeds and the energy is unbillable.\n\nGated because installing is an upsert keyed on the EMAID, not an insert: an\nunchecked caller could re-register a contract that is already another\nhost's and carry the `org_id` over to themselves.","operationId":"host_install_contract_v1_host_pnc_contracts_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/pnc/contracts-expiring":{"get":{"tags":["host"],"summary":"Host Expiring Contracts","description":"Contracts about to lapse.\n\nA driver experiences an expired contract as Plug & Charge simply having\nstopped working, and concludes the charger is broken.","operationId":"host_expiring_contracts_v1_host_pnc_contracts_expiring_get","parameters":[{"name":"days_ahead","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days Ahead"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/regulatory/reports":{"get":{"tags":["host"],"summary":"Host Reports","description":"Returns filed with the authority, and what came back.\n\nScoped by site rather than by organisation, unlike the contracts above: a\nreport records the site it covers, but nothing populates its `org_id`. A\nnetwork-wide filing carries no site, belongs to no one host, and is\nwithheld from all of them.","operationId":"host_reports_v1_host_regulatory_reports_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/host/regulatory/build":{"post":{"tags":["host"],"summary":"Host Build Report","description":"Compute a period's figures and freeze them.\n\nA period already built returns what was stored — a figure that has been\nfiled must not change underneath whoever filed it.\n\nNaming a site scopes the build to it. Omitting one still builds the whole\nnetwork's return, because a site is the only dimension the CSMS scopes a\nbuild by — so this is restricted to hosts, but not yet to one host's own\nfigures. Narrowing it further is a product decision, not a bug fix: it\nwould change what a host who files for their whole account gets back.","operationId":"host_build_report_v1_host_regulatory_build_post","parameters":[{"name":"period","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Period"}},{"name":"site_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Site Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/queue/join":{"post":{"tags":["queue"],"summary":"Join Queue","description":"Take a place in the line for a charger.\n\nUnlike a reservation this does not idle the bay: the connector keeps\nworking and is offered to whoever is next when it actually frees. Joining\ntwice returns the same place rather than a second one.","operationId":"join_queue_v1_queue_join_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JoinIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/queue/mine":{"get":{"tags":["queue"],"summary":"My Queue Entries","description":"Where this driver is waiting, and how far up the line.\n\nReturns the open entries first so a client can show \"you're next\" without\nfiltering — the offer is the only one that needs acting on.","operationId":"my_queue_entries_v1_queue_mine_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/queue/{ocpp_identity}":{"get":{"tags":["queue"],"summary":"Queue At","description":"How busy a charger is before deciding to drive to it.\n\nOnly the length and the wait are returned — who is in the queue is nobody\nelse's business, and a driver deciding where to charge does not need it.","operationId":"queue_at_v1_queue__ocpp_identity__get","parameters":[{"name":"ocpp_identity","in":"path","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/queue/{entry_id}/leave":{"post":{"tags":["queue"],"summary":"Leave Queue","description":"Give up a place.\n\nIdempotent: leaving an entry that is already gone succeeds. A driver\ntapping twice, or leaving from a second device, should not see an error for\nsomething that has already happened.\n\nYours, though. `entry_id` is the CSMS's own row id and it is sequential, so\nwithout this check any signed-in driver could count upwards and evict\neverybody else from every queue on the network — and the victims would see\nonly that they had lost their place. The same shape as `_owned_session` in\n`roaming.py`, which exists for exactly this reason.","operationId":"leave_queue_v1_queue__entry_id__leave_post","parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","maximum":2147483647,"title":"Entry Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/reservations":{"get":{"tags":["reservations"],"summary":"My Reservations","description":"The driver's active reservations (lapsed ones are retired first).","operationId":"my_reservations_v1_reservations_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["reservations"],"summary":"Create Reservation","description":"Hold a connector for this driver until `minutes` from now. Asks the\ncharger via the CSMS; only persisted if the charger accepts.","operationId":"create_reservation_v1_reservations_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReserveIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/reservations/{res_id}":{"delete":{"tags":["reservations"],"summary":"Delete Reservation","description":"Cancel a reservation.\n\nAllowed for the driver who made it *and* for the owner of the charger it is\nheld on — the owner console lists every active hold on their charger,\nincluding other drivers', and must be able to release them.","operationId":"delete_reservation_v1_reservations__res_id__delete","parameters":[{"name":"res_id","in":"path","required":true,"schema":{"type":"string","title":"Res Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/reservations/options":{"get":{"tags":["reservations"],"summary":"Reservable Connectors","description":"Which plugs a driver can hold here, and what each one is.\n\nExists because the reserve endpoint takes an integer, and an integer is not\nsomething a driver knows. Holding \"connector 2\" is only useful if they can\ntell on arrival which bay that is — so the choice is offered in the terms\nthe site is labelled in.","operationId":"reservable_connectors_v1_reservations_options_get","parameters":[{"name":"ocpp_identity","in":"query","required":true,"schema":{"type":"string","title":"Ocpp Identity"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Reservable Connectors V1 Reservations Options Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/roaming/start":{"post":{"tags":["roaming"],"summary":"Start","description":"Ask a partner to start a charge for the signed-in driver.\n\nReturns `command_id` to poll. Nothing is billed here — the money moves when\nthe partner sends their Charge Detail Record, because until then nobody\nknows how much energy was delivered.","operationId":"start_v1_roaming_start_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoamingStartIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/roaming/stop":{"post":{"tags":["roaming"],"summary":"Stop","description":"Stop a charge running on a partner's network.","operationId":"stop_v1_roaming_stop_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoamingStopIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/roaming/commands/{command_id}":{"get":{"tags":["roaming"],"summary":"Command","description":"Where a start or stop got to.\n\n`pending` is a real answer and the common one for the first few seconds:\nthe partner has the message and their charger has not reported back. The app\nkeeps the driver on a spinner until this resolves or times out.","operationId":"command_v1_roaming_commands__command_id__get","parameters":[{"name":"command_id","in":"path","required":true,"schema":{"type":"string","title":"Command Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/roaming/sessions":{"get":{"tags":["roaming"],"summary":"Sessions","description":"This driver's roaming charges, newest first.","operationId":"sessions_v1_roaming_sessions_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/roaming/sessions/{roaming_session_id}":{"get":{"tags":["roaming"],"summary":"Session","description":"One roaming charge, including live energy while it runs.","operationId":"session_v1_roaming_sessions__roaming_session_id__get","parameters":[{"name":"roaming_session_id","in":"path","required":true,"schema":{"type":"integer","title":"Roaming Session Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/stations/{station_id}/reviews":{"get":{"tags":["reviews"],"summary":"List Reviews","description":"Public. Visible reviews for a station, newest first, plus the summary\nthe station header shows.","operationId":"list_reviews_v1_stations__station_id__reviews_get","parameters":[{"name":"station_id","in":"path","required":true,"schema":{"type":"string","title":"Station Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Reviews V1 Stations  Station Id  Reviews Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["reviews"],"summary":"Create Review","operationId":"create_review_v1_stations__station_id__reviews_post","parameters":[{"name":"station_id","in":"path","required":true,"schema":{"type":"string","title":"Station Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Review V1 Stations  Station Id  Reviews Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/stations/{station_id}/reviews/eligibility":{"get":{"tags":["reviews"],"summary":"Review Eligibility","description":"Which of my sessions at this station can still be reviewed.\n\nThe app calls this before showing the \"Write a review\" action, so the\nbutton is never offered and then refused.","operationId":"review_eligibility_v1_stations__station_id__reviews_eligibility_get","parameters":[{"name":"station_id","in":"path","required":true,"schema":{"type":"string","title":"Station Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Review Eligibility V1 Stations  Station Id  Reviews Eligibility Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/stations/{station_id}/reports":{"post":{"tags":["reviews"],"summary":"Report Problem","description":"Report a problem. Unlike a review this needs no prior session — you may\nwell be standing at a charger that will not start, which is precisely the\nreport worth having.","operationId":"report_problem_v1_stations__station_id__reports_post","parameters":[{"name":"station_id","in":"path","required":true,"schema":{"type":"string","title":"Station Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProblemIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Report Problem V1 Stations  Station Id  Reports Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/analytics/summary":{"get":{"tags":["owner-analytics"],"summary":"Summary","description":"Headline metrics for the overview grid.","operationId":"summary_v1_owner_analytics_summary_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":1,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Summary V1 Owner Analytics Summary Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/analytics/utilisation":{"get":{"tags":["owner-analytics"],"summary":"Utilisation","description":"Energy per month per station — the \"is this site getting better\" series.\n\nReturned as one series per station so the client can draw a line each. The\nclient caps at 6 series and folds the rest into \"Other\"; the categorical\npalette is only validated to six.","operationId":"utilisation_v1_owner_analytics_utilisation_get","parameters":[{"name":"months","in":"query","required":false,"schema":{"type":"integer","maximum":24,"minimum":1,"default":12,"title":"Months"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Utilisation V1 Owner Analytics Utilisation Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/analytics/by-site":{"get":{"tags":["owner-analytics"],"summary":"By Site","description":"Energy and revenue per site — the bar chart, and the table view under it.\n\nA site with zero energy is returned explicitly rather than omitted: an\nabsent bar reads as \"no data\", a zero bar labelled `offline` reads as the\nproblem it actually is.","operationId":"by_site_v1_owner_analytics_by_site_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":1,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response By Site V1 Owner Analytics By Site Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/analytics/occupancy":{"get":{"tags":["owner-analytics"],"summary":"Occupancy","description":"Sessions by weekday × hour — the heat calendar.\n\nReturned as a 7×24 integer grid, plus the max, so the client can map onto a\nsequential ramp without a second round trip. One hue, light to dark: rank\nhas to be readable without a legend.","operationId":"occupancy_v1_owner_analytics_occupancy_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":7,"default":28,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Occupancy V1 Owner Analytics Occupancy Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/operator/application":{"get":{"tags":["operator"],"summary":"My Application","description":"Where my application is, and what is needed.\n\nReturns `null` rather than 404 for somebody who has not applied. A missing\napplication is a normal state for every driver on the platform, and making\nthe client treat it as an error means every caller writes the same\ntry/except around a thing that is not wrong.","operationId":"my_application_v1_operator_application_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["operator"],"summary":"Upsert Application","description":"Create or update my application.\n\nA PUT, not a POST: there is one application per user and sending it twice\nshould leave one. The alternative — POST creating a second row — gives\nstaff two versions of the same business to reconcile.","operationId":"upsert_application_v1_operator_application_put","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/operator/team":{"get":{"tags":["operator"],"summary":"My Team","description":"Who can see my chargers, and the team I am on.\n\nBoth halves in one answer, because an account is on exactly one side of\nthis and the client should not have to ask twice to find out which.","operationId":"my_team_v1_operator_team_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/operator/team/invite":{"post":{"tags":["operator"],"summary":"Invite Member","description":"Let somebody else work on my chargers.\n\nAn invitation is addressed to an email rather than to an account, because\nthe person being invited usually does not have one yet — requiring them to\nsign up first, unprompted, is how an invitation goes unanswered.","operationId":"invite_member_v1_operator_team_invite_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/operator/team/accept":{"post":{"tags":["operator"],"summary":"Accept Invite","description":"Join the team that invited this account's email address.\n\nMatched on the verified email rather than on a token in a link. The address\nis already proven by sign-in, and a token would be a second secret to email,\nexpire and support.","operationId":"accept_invite_v1_operator_team_accept_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/operator/team/{member_id}":{"delete":{"tags":["operator"],"summary":"Remove Member","description":"Take somebody off my team, or leave one I am on.\n\nBoth are the same row, so both are the same route. Removal is immediate:\n`host_id_for` reads this table on every scoped request, so access ends on\nthe next one rather than whenever a cached token expires.","operationId":"remove_member_v1_operator_team__member_id__delete","parameters":[{"name":"member_id","in":"path","required":true,"schema":{"type":"integer","title":"Member Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/applications":{"get":{"tags":["admin"],"summary":"Application Queue","description":"The queue, oldest first.\n\nOldest first is the whole point: newest-first is how an application that\nnobody wanted to deal with stays at the bottom forever.","operationId":"application_queue_v1_admin_applications_get","parameters":[{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/applications/{application_id}/decide":{"post":{"tags":["admin"],"summary":"Decide","description":"Approve or reject, and say why.\n\nApproving promotes the applicant to `host`. Rejecting does not demote\nanybody: a driver who was already a host through the app's own \"Become a\nhost\" flow keeps whatever they had, because taking access away is a\ndifferent decision from declining to grant it and should be made\ndeliberately rather than as a side effect of this one.","operationId":"decide_v1_admin_applications__application_id__decide_post","parameters":[{"name":"application_id","in":"path","required":true,"schema":{"type":"integer","title":"Application Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/applications/{application_id}/claim":{"post":{"tags":["admin"],"summary":"Claim","description":"Take an application off the unclaimed pile.\n\nOnly moves `submitted` to `in_review`, and never touches a decided one —\ntwo reviewers opening the same queue should not be able to undo each\nother's work by clicking first.","operationId":"claim_v1_admin_applications__application_id__claim_post","parameters":[{"name":"application_id","in":"path","required":true,"schema":{"type":"integer","title":"Application Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/payouts":{"get":{"tags":["admin"],"summary":"All Payouts","description":"Every host's statements, oldest unpaid first.\n\nOrdered by period ascending rather than descending, which is the opposite\nof the host-facing list and deliberate: a host wants their latest\nstatement, while the person doing a payout run wants the one that has been\nowed longest. Sorting a disbursement queue newest-first is how a statement\nfrom four months ago quietly never gets paid.\n\nDefaults to what is actually actionable — closed statements that have not\nsettled. `state` widens it when somebody is looking for a specific one.","operationId":"all_payouts_v1_admin_payouts_get","parameters":[{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/branding":{"get":{"tags":["owner-branding"],"summary":"Get Branding","operationId":"get_branding_v1_owner_branding_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Branding V1 Owner Branding Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["owner-branding"],"summary":"Upsert Branding","operationId":"upsert_branding_v1_owner_branding_put","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandingIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Upsert Branding V1 Owner Branding Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/branding/public/{host_id}":{"get":{"tags":["owner-branding"],"summary":"Public Branding","description":"Unauthenticated. The driver app reads this to co-brand a station page\nand a receipt — it must work before sign-in, and for a driver who belongs\nto no franchise at all.","operationId":"public_branding_v1_owner_branding_public__host_id__get","parameters":[{"name":"host_id","in":"path","required":true,"schema":{"type":"integer","title":"Host Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Public Branding V1 Owner Branding Public  Host Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/media/campaigns":{"get":{"tags":["media"],"summary":"List Campaigns","operationId":"list_campaigns_v1_media_campaigns_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Campaigns V1 Media Campaigns Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["media"],"summary":"Create Campaign","operationId":"create_campaign_v1_media_campaigns_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Campaign V1 Media Campaigns Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/media/campaigns/{campaign_id}/targets":{"post":{"tags":["media"],"summary":"Add Target","operationId":"add_target_v1_media_campaigns__campaign_id__targets_post","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TargetIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Add Target V1 Media Campaigns  Campaign Id  Targets Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/media/creatives/{creative_id}/approve":{"post":{"tags":["media"],"summary":"Approve Creative","description":"Approval is the gate. Until this runs the creative cannot be served.","operationId":"approve_creative_v1_media_creatives__creative_id__approve_post","parameters":[{"name":"creative_id","in":"path","required":true,"schema":{"type":"integer","title":"Creative Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Approve Creative V1 Media Creatives  Creative Id  Approve Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/media/players":{"get":{"tags":["media"],"summary":"List Players","description":"Player health. An operator sees only their own sites; an admin sees all.\n\nHealth sits on the same board as delivery because a campaign is only\ndelivering if the box is alive.","operationId":"list_players_v1_media_players_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Players V1 Media Players Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/media/players/{hardware_id}/heartbeat":{"post":{"tags":["media"],"summary":"Heartbeat","description":"Called by the player box itself, with the shared player secret.","operationId":"heartbeat_v1_media_players__hardware_id__heartbeat_post","parameters":[{"name":"hardware_id","in":"path","required":true,"schema":{"type":"string","title":"Hardware Id"}},{"name":"x-player-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Player-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeartbeatIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Heartbeat V1 Media Players  Hardware Id  Heartbeat Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/media/players/{hardware_id}/plays":{"post":{"tags":["media"],"summary":"Report Play","description":"Proof of play, append-only and idempotent.\n\nA duplicate key returns 200 with `duplicate: true` rather than an error —\na replaying player is behaving correctly, and an error would make it retry\nforever.","operationId":"report_play_v1_media_players__hardware_id__plays_post","parameters":[{"name":"hardware_id","in":"path","required":true,"schema":{"type":"string","title":"Hardware Id"}},{"name":"x-player-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Player-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Report Play V1 Media Players  Hardware Id  Plays Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/media/plays":{"get":{"tags":["media"],"summary":"List Plays","operationId":"list_plays_v1_media_plays_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Plays V1 Media Plays Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/media/revenue-share":{"get":{"tags":["media"],"summary":"Revenue Share","description":"What this operator is owed. Settles through the existing payouts path.","operationId":"revenue_share_v1_media_revenue_share_get","parameters":[{"name":"period","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Period"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Revenue Share V1 Media Revenue Share Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/media/summary":{"get":{"tags":["media"],"summary":"Media Summary","description":"The board at the top of the media console.","operationId":"media_summary_v1_media_summary_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Media Summary V1 Media Summary Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/finance/reconciliation":{"get":{"tags":["finance"],"summary":"Payment Reconciliation","description":"Where our record of a payment and the provider's disagree.\n\nThe default window is deliberately short. It has to comfortably exceed the\nprovider's own settlement lag — a payment still in flight is not a\ndivergence — and past that, re-checking history re-answers a question every\nprevious run already answered.\n\nThree kinds of disagreement, and they mean opposite things:\n\n* `credited_but_not_captured` — we believe we hold money we do not. A bug\n  in settlement, or somebody who found a way through it.\n* `captured_but_not_credited` — a driver paid and was not credited. They\n  will notice, and by then it is a support ticket rather than an alert.\n* `amount_mismatch` — both sides moved money, for different amounts.","operationId":"payment_reconciliation_v1_finance_reconciliation_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":2,"title":"Days"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":2000,"minimum":1,"default":500,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Payment Reconciliation V1 Finance Reconciliation Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/finance/gst/table-11a":{"get":{"tags":["finance"],"summary":"Gstr1 Table 11A","description":"Advances received in a period, net of advances returned.\n\nNet, because that is what the table asks for. Reporting receipts gross and\nhandling the reversals somewhere else is how a return overstates a\nliability on money that was already given back.\n\nEvery voucher in the window is listed alongside the totals, so a figure can\nbe traced to the documents behind it rather than taken on trust — which is\nthe difference between an extract somebody can file and a number somebody\nhas to verify by hand.","operationId":"gstr1_table_11a_v1_finance_gst_table_11a_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":31,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Gstr1 Table 11A V1 Finance Gst Table 11A Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/finance/gst/financial-year":{"get":{"tags":["finance"],"summary":"Current Financial Year","description":"Which year vouchers are being numbered against right now.\n\nSequences restart on 1 April, and a sequence that restarts in the middle of\na year is exactly the defect a filing gets checked for. Cheap to expose,\nand the fastest way to notice the boundary was computed wrongly.","operationId":"current_financial_year_v1_finance_gst_financial_year_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Current Financial Year V1 Finance Gst Financial Year Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/charger-status":{"post":{"tags":["internal"],"summary":"Charger Status","description":"Called by the OCPP service when a charger connects/disconnects. Marks the\ncharge point online, and the first time a real charger comes online it\npublishes its station (pending → active), so only stations with real,\nconnected hardware appear on the driver map.","operationId":"charger_status_v1_internal_charger_status_post","parameters":[{"name":"x-service-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Service-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChargerStatusIn"}}}},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/authorize":{"post":{"tags":["internal"],"summary":"Authorize","description":"Decide whether an RFID card / idToken may charge on this charger.\n\nA 404 means \"the platform has never heard of this card\" — a definitive no,\nwhich the CSMS records as such. Anything else that goes wrong here returns a\n5xx instead, so the CSMS can tell \"rejected\" from \"could not ask\" and fall\nback to its own authorization cache rather than stranding a known driver\nduring a backend outage.","operationId":"authorize_v1_internal_authorize_post","parameters":[{"name":"x-service-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Service-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthorizeIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthorizeOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/charger-qr":{"post":{"tags":["internal"],"summary":"Charger Qr","description":"Mint a payable QR for a walk-up charge, on the provider's ledger.\n\nThe CSMS used to build `upi://pay?pa=<our vpa>&am=...` itself and put that\non the charger's display. Money arrived — and arrived outside the\nprovider's ledger: no webhook, no settlement row, nothing to reconcile\nagainst, and no answer to \"did my payment go through\" beyond reading a bank\nstatement. Every recovery path in this codebase assumes the provider knows\nabout the payment.\n\nSo the URI is minted here instead. `image_content` on the provider's QR\nentity is a `upi://` string of exactly the shape the hand-built one had,\nwhich is why nothing downstream of the charger's display has to change.\n\nRecorded as a `GuestCharge` keyed on the QR id, so the walk-up flow and the\napp's guest flow settle through the same machinery rather than two\nimplementations that drift.","operationId":"charger_qr_v1_internal_charger_qr_post","parameters":[{"name":"x-service-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Service-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChargerQrRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Charger Qr V1 Internal Charger Qr Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/sessions":{"post":{"tags":["internal"],"summary":"Record Internal Session","description":"Record a session the CSMS forwarded for a driver who never opened the app.\n\nDeliberately separate from the user-facing `POST /v1/sessions`: that one\nderives the account from the caller's own token and must keep doing so.\nHere the account comes from `user_ref`, which is only trustworthy because\nthe service token gates the endpoint.\n\nIdempotent on `external_id`, so the CSMS outbox can retry a delivery it is\nunsure about without billing the driver twice.","operationId":"record_internal_session_v1_internal_sessions_post","parameters":[{"name":"x-service-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Service-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalSessionIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/roaming-authorize":{"post":{"tags":["internal"],"summary":"Roaming Authorize","description":"May this driver of ours charge on a partner's network right now?\n\nA 404 means the token was never ours — a definitive no. Anything that goes\nwrong internally must surface as a 5xx instead, because the CSMS refuses the\ncharge when it cannot get an answer, and a 200 saying \"no\" would make a\ntransient failure look like a deliberate refusal in every log downstream.","operationId":"roaming_authorize_v1_internal_roaming_authorize_post","parameters":[{"name":"x-service-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Service-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoamingAuthorizeIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/roaming-session":{"post":{"tags":["internal"],"summary":"Record Roaming Session","description":"Bill a driver for a charge taken on a partner's network.\n\nIdempotent on the CSMS's roaming session id: the partner may re-push the\nsame CDR and the CSMS retries settlement, so this endpoint is reached more\nthan once for a single charge by design. Charging twice for one plug-in is\nthe failure it exists to prevent.","operationId":"record_roaming_session_v1_internal_roaming_session_post","parameters":[{"name":"x-service-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Service-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoamingSessionIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/alerts":{"post":{"tags":["internal"],"summary":"Receive Alert","description":"Accept an alert from the charging network.\n\nAnswers 202 rather than 201 because the interesting work — attributing it to\na host and deciding whether to interrupt them — is done here, and the CSMS\nonly needs to know the alert is no longer its problem.","operationId":"receive_alert_v1_internal_alerts_post","parameters":[{"name":"x-service-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Service-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertIn"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/plugged-in":{"post":{"tags":["internal"],"summary":"Report Plug In","description":"A car was plugged in, or unplugged. Tell whoever should know.\n\nThe identity chain, and its one weak link, is documented in\n`services/plugged_in.py`. In short: OCPP gives us \"something is plugged\nin\"; Autocharge may add the car's MAC; nothing gives a number plate. The\nMAC is matched against bindings we learned by watching, so a car is\nrecognised only after its owner has once started a charge on it.","operationId":"report_plug_in_v1_internal_plugged_in_post","parameters":[{"name":"x-service-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Service-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlugIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Report Plug In V1 Internal Plugged In Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/waitlist":{"post":{"tags":["website"],"summary":"Join Waitlist","operationId":"join_waitlist_api_v1_waitlist_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/partner":{"post":{"tags":["website"],"summary":"Submit Partner Request","operationId":"submit_partner_request_api_v1_partner_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/roaming-enquiry":{"post":{"tags":["website"],"summary":"Submit Roaming Enquiry","description":"A charging network asking to peer with us over OCPI.\n\nRecords the request; it does not issue credentials. Anyone who completes an\nOCPI handshake can start sessions on our hosts' chargers and owes us for the\nenergy afterwards, which makes peering a billing relationship — so a person\nreads this and signs an agreement before a token exists.\n\nRe-submitting for the same party updates the existing row rather than\ncreating a duplicate: an integrator who fills the form twice while chasing a\nreply is the normal case, not a second network.","operationId":"submit_roaming_enquiry_api_v1_roaming_enquiry_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoamingEnquiryCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoamingEnquiryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users":{"post":{"tags":["website"],"summary":"Create Demo User","operationId":"create_demo_user_api_v1_users_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DemoUserCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DemoUserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/{user_id}":{"get":{"tags":["website"],"summary":"Read Demo User","operationId":"read_demo_user_api_v1_users__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DemoUserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/chargers":{"get":{"tags":["website"],"summary":"List Chargers","operationId":"list_chargers_api_v1_chargers_get","parameters":[{"name":"shared_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Shared Only"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChargerResponse"},"title":"Response List Chargers Api V1 Chargers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["website"],"summary":"Create Charger","operationId":"create_charger_api_v1_chargers_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__schemas__website__ChargerCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChargerResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/bookings":{"post":{"tags":["website"],"summary":"Create Booking","operationId":"create_booking_api_v1_bookings_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/bookings/{booking_id}/end":{"post":{"tags":["website"],"summary":"End Booking","operationId":"end_booking_api_v1_bookings__booking_id__end_post","parameters":[{"name":"booking_id","in":"path","required":true,"schema":{"type":"integer","title":"Booking Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"tags":["meta"],"summary":"Root","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"tags":["meta"],"summary":"Health","description":"Liveness, plus the one fact that decides whether the answer is worth\nanything: can this process reach its database.\n\nThis used to return a constant. A constant cannot fail, which makes it\nindistinguishable from a check that passed — so a container whose\ndatabase was unreachable reported itself healthy, kept its place behind\nthe load balancer, and served 500s to every request while the dashboard\nshowed green. The most misleading answer available is a cheerful one.\n\nReported in the body rather than as a 5xx, matching the CSMS's own\n`/health`: a health endpoint that raises gives an operator no detail at\nthe moment they most need it. Note that Railway and most orchestrators\nroute on the status code alone, so this reports the truth without\nchanging deploy behaviour — turning `degraded` into a 503 is a separate\ndecision about whether a database blip should pull the app out of\nrotation.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/privacy":{"get":{"tags":["meta"],"summary":"Privacy Policy","description":"Public privacy policy page (used as the Play Store privacy URL).","operationId":"privacy_policy_privacy_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}}},"components":{"schemas":{"AlertAckIn":{"properties":{"alert_id":{"type":"integer","title":"Alert Id"},"resolve":{"type":"boolean","title":"Resolve","default":false}},"type":"object","required":["alert_id"],"title":"AlertAckIn"},"AlertIn":{"properties":{"identity":{"type":"string","maxLength":64,"minLength":1,"title":"Identity"},"kind":{"type":"string","maxLength":40,"title":"Kind","default":"anomaly"},"severity":{"type":"string","maxLength":12,"title":"Severity","default":"warning"},"title":{"type":"string","maxLength":200,"title":"Title","default":""},"detail":{"type":"string","title":"Detail","default":""},"context":{"additionalProperties":true,"type":"object","title":"Context"},"fingerprint":{"type":"string","maxLength":64,"title":"Fingerprint","default":""},"raised_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Raised At"},"driver_ref":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Driver Ref"}},"type":"object","required":["identity"],"title":"AlertIn"},"ApplicationIn":{"properties":{"entity_name":{"type":"string","maxLength":160,"minLength":2,"title":"Entity Name"},"entity_type":{"type":"string","maxLength":32,"title":"Entity Type","default":"other"},"contact_name":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Contact Name"},"contact_phone":{"anyOf":[{"type":"string","maxLength":24},{"type":"null"}],"title":"Contact Phone"},"gstin":{"anyOf":[{"type":"string","maxLength":15},{"type":"null"}],"title":"Gstin"},"pan":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Pan"},"site_city":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Site City"},"site_state":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Site State"},"site_count":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Site Count","default":1},"site_notes":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"title":"Site Notes"},"submit":{"type":"boolean","title":"Submit","default":false}},"type":"object","required":["entity_name"],"title":"ApplicationIn"},"AssignChargerIn":{"properties":{"site_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Site Id"},"max_power_kw":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Max Power Kw"},"priority":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Priority"},"is_swap_station":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Swap Station"}},"type":"object","title":"AssignChargerIn"},"AuthTokenIn":{"properties":{"id_tag":{"type":"string","title":"Id Tag"},"label":{"type":"string","title":"Label","default":""},"parent_id_tag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id Tag"},"status":{"type":"string","title":"Status","default":"Accepted"},"expiry":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expiry"}},"type":"object","required":["id_tag"],"title":"AuthTokenIn"},"AuthorizeIn":{"properties":{"id_tag":{"type":"string","maxLength":64,"minLength":1,"title":"Id Tag"},"ocpp_identity":{"type":"string","maxLength":64,"minLength":1,"title":"Ocpp Identity"},"connector_id":{"type":"integer","title":"Connector Id","default":0},"ocpp_version":{"type":"string","title":"Ocpp Version","default":"1.6"}},"type":"object","required":["id_tag","ocpp_identity"],"title":"AuthorizeIn"},"AuthorizeOut":{"properties":{"status":{"type":"string","title":"Status"},"reason":{"type":"string","title":"Reason","default":""},"parent_id_tag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id Tag"},"expiry_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expiry Date"},"user_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Ref"},"balance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Balance"},"currency":{"type":"string","title":"Currency","default":"INR"},"autocharge_limit":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Autocharge Limit"},"user_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Name"}},"type":"object","required":["status"],"title":"AuthorizeOut"},"AvailabilityIn":{"properties":{"connector_id":{"type":"integer","title":"Connector Id","default":0},"type":{"type":"string","title":"Type","default":"Inoperative"}},"type":"object","title":"AvailabilityIn"},"BaseReportIn":{"properties":{"request_id":{"type":"integer","title":"Request Id","default":1},"report_base":{"type":"string","title":"Report Base","default":"FullInventory"}},"type":"object","title":"BaseReportIn"},"Body_upload_station_photo_v1_stations__station_id__photos_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"caption":{"type":"string","title":"Caption","default":""}},"type":"object","required":["file"],"title":"Body_upload_station_photo_v1_stations__station_id__photos_post"},"BookingCreate":{"properties":{"user_id":{"type":"integer","title":"User Id"},"charger_id":{"type":"integer","title":"Charger Id"}},"type":"object","required":["user_id","charger_id"],"title":"BookingCreate"},"BookingResponse":{"properties":{"id":{"type":"integer","title":"Id"},"user_id":{"type":"integer","title":"User Id"},"charger_id":{"type":"integer","title":"Charger Id"},"start_time":{"type":"string","title":"Start Time"},"end_time":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"End Time"},"total_cost":{"type":"number","title":"Total Cost"},"status":{"type":"string","title":"Status"}},"type":"object","required":["id","user_id","charger_id","start_time","end_time","total_cost","status"],"title":"BookingResponse"},"BrandingIn":{"properties":{"display_name":{"type":"string","maxLength":80,"minLength":1,"title":"Display Name"},"brand_color":{"type":"string","title":"Brand Color"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"operated_by_line":{"anyOf":[{"type":"string","maxLength":160},{"type":"null"}],"title":"Operated By Line"}},"type":"object","required":["display_name","brand_color"],"title":"BrandingIn"},"CampaignIn":{"properties":{"advertiser_id":{"type":"integer","title":"Advertiser Id"},"name":{"type":"string","maxLength":160,"minLength":1,"title":"Name"},"starts_at":{"type":"string","format":"date-time","title":"Starts At"},"ends_at":{"type":"string","format":"date-time","title":"Ends At"},"budget_paise":{"type":"integer","minimum":0.0,"title":"Budget Paise"},"pricing_model":{"type":"string","title":"Pricing Model","default":"cpm"}},"type":"object","required":["advertiser_id","name","starts_at","ends_at","budget_paise"],"title":"CampaignIn"},"ChangeConfigIn":{"properties":{"key":{"type":"string","title":"Key"},"value":{"type":"string","title":"Value"}},"type":"object","required":["key","value"],"title":"ChangeConfigIn"},"ChargeStopOut":{"properties":{"station_id":{"type":"string","title":"Station Id"},"name":{"type":"string","title":"Name"},"is_public":{"type":"boolean","title":"Is Public","default":false},"connectors":{"items":{"type":"string"},"type":"array","title":"Connectors"},"amenities":{"items":{"type":"string"},"type":"array","title":"Amenities"},"price_per_kwh":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Per Kwh"},"cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost"},"power_known":{"type":"boolean","title":"Power Known","default":true},"expected_power_kw":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Power Kw"},"power_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Power Note"},"good_for_a_break":{"type":"boolean","title":"Good For A Break","default":false},"latitude":{"type":"number","title":"Latitude"},"longitude":{"type":"number","title":"Longitude"},"max_power_kw":{"type":"integer","title":"Max Power Kw"},"along_km":{"type":"number","title":"Along Km"},"detour_km":{"type":"number","title":"Detour Km"},"arrival_soc":{"type":"integer","title":"Arrival Soc"},"depart_soc":{"type":"integer","title":"Depart Soc"},"charge_minutes":{"type":"integer","title":"Charge Minutes"},"energy_kwh":{"type":"number","title":"Energy Kwh"}},"type":"object","required":["station_id","name","latitude","longitude","max_power_kw","along_km","detour_km","arrival_soc","depart_soc","charge_minutes","energy_kwh"],"title":"ChargeStopOut"},"ChargerOut":{"properties":{"id":{"type":"integer","title":"Id"},"ocpp_identity":{"type":"string","title":"Ocpp Identity"},"name":{"type":"string","title":"Name"},"station_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Station Id"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","ocpp_identity","name","station_id","created_at"],"title":"ChargerOut"},"ChargerQrRequest":{"properties":{"ocpp_identity":{"type":"string","maxLength":64,"minLength":1,"title":"Ocpp Identity"},"connector_id":{"type":"integer","maximum":16.0,"minimum":1.0,"title":"Connector Id","default":1},"amount":{"type":"number","maximum":10000.0,"exclusiveMinimum":0.0,"title":"Amount"},"ttl_seconds":{"type":"integer","maximum":7200.0,"minimum":60.0,"title":"Ttl Seconds","default":600}},"type":"object","required":["ocpp_identity","amount"],"title":"ChargerQrRequest","description":"A QR for the screen on the charger itself, asked for by the CSMS."},"ChargerResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"latitude":{"type":"number","title":"Latitude"},"longitude":{"type":"number","title":"Longitude"},"price_per_kwh":{"type":"number","title":"Price Per Kwh"},"status":{"type":"string","title":"Status"},"is_shared":{"type":"boolean","title":"Is Shared"},"host_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Host Id"}},"type":"object","required":["id","name","latitude","longitude","price_per_kwh","status","is_shared","host_id"],"title":"ChargerResponse"},"ChargerStatusIn":{"properties":{"ocpp_identity":{"type":"string","title":"Ocpp Identity"},"connected":{"type":"boolean","title":"Connected"}},"type":"object","required":["ocpp_identity","connected"],"title":"ChargerStatusIn"},"ChargerUpdate":{"properties":{"station_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Station Id"}},"type":"object","required":["station_id"],"title":"ChargerUpdate","description":"Attach an already-registered charger to one of the owner's stations\n(or detach it with an explicit null).\n\nChargers registered before a station existed have `station_id = NULL`, and a\nstation with no charger cannot report an `ocpp_identity` — so the driver app\nfalls back to the CSMS default charge point. This is the repair path."},"ChargingProfileIn":{"properties":{"connector_id":{"type":"integer","title":"Connector Id","default":1},"limit":{"type":"number","title":"Limit"},"unit":{"type":"string","title":"Unit","default":"W"}},"type":"object","required":["limit"],"title":"ChargingProfileIn"},"ClaimDecision":{"properties":{"approve":{"type":"boolean","title":"Approve"}},"type":"object","required":["approve"],"title":"ClaimDecision"},"ClearMonitoringIn":{"properties":{"ids":{"items":{"type":"integer"},"type":"array","title":"Ids"}},"type":"object","required":["ids"],"title":"ClearMonitoringIn"},"ClosePeriodIn":{"properties":{"period":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Period"},"all_hosts":{"type":"boolean","title":"All Hosts","default":false},"host_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Host Id"}},"type":"object","title":"ClosePeriodIn"},"CommandIn":{"properties":{"action":{"type":"string","title":"Action"},"payload":{"additionalProperties":true,"type":"object","title":"Payload","default":{}}},"type":"object","required":["action"],"title":"CommandIn"},"ComplianceIn":{"properties":{"bis_standard":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bis Standard"},"bis_certificate":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bis Certificate"},"certified_until":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Certified Until"}},"type":"object","title":"ComplianceIn"},"ConnectorOut":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"connector_type":{"type":"string","title":"Connector Type"},"power_kw":{"type":"integer","title":"Power Kw"},"current":{"type":"string","title":"Current"},"available":{"type":"integer","title":"Available"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["id","name","connector_type","power_kw","current","available","total"],"title":"ConnectorOut"},"ContractIn":{"properties":{"emaid":{"type":"string","title":"Emaid"},"account_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Ref"},"valid_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Valid Until"},"issuer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Issuer"}},"type":"object","required":["emaid"],"title":"ContractIn"},"CorridorChargerOut":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"latitude":{"type":"number","title":"Latitude"},"longitude":{"type":"number","title":"Longitude"},"max_power_kw":{"type":"integer","title":"Max Power Kw"},"power_known":{"type":"boolean","title":"Power Known"},"is_public":{"type":"boolean","title":"Is Public"},"connectors":{"items":{"type":"string"},"type":"array","title":"Connectors"},"along_km":{"type":"number","title":"Along Km"},"detour_km":{"type":"number","title":"Detour Km"}},"type":"object","required":["id","name","latitude","longitude","max_power_kw","power_known","is_public","connectors","along_km","detour_km"],"title":"CorridorChargerOut","description":"A charger the route passes, whether or not the plan stops at it."},"DataTransferIn":{"properties":{"vendor_id":{"type":"string","title":"Vendor Id"},"message_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message Id"},"data":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Data"}},"type":"object","required":["vendor_id"],"title":"DataTransferIn"},"DecisionIn":{"properties":{"approve":{"type":"boolean","title":"Approve"},"reason":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Reason"}},"type":"object","required":["approve"],"title":"DecisionIn"},"DeficitOut":{"properties":{"id":{"type":"integer","title":"Id"},"amount":{"type":"number","title":"Amount"},"recovered":{"type":"number","title":"Recovered"},"outstanding":{"type":"number","title":"Outstanding"},"currency":{"type":"string","title":"Currency"},"reason":{"type":"string","title":"Reason"},"session_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Session Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","amount","recovered","outstanding","currency","reason","session_id","created_at"],"title":"DeficitOut","description":"Money owed from a session that cost more than was secured."},"DemoUserCreate":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"name":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Name"}},"type":"object","required":["email"],"title":"DemoUserCreate"},"DemoUserResponse":{"properties":{"id":{"type":"integer","title":"Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"wallet_balance":{"type":"number","title":"Wallet Balance"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","email","name","wallet_balance","created_at"],"title":"DemoUserResponse"},"DeviceIn":{"properties":{"token":{"type":"string","maxLength":256,"minLength":8,"title":"Token"},"platform":{"type":"string","maxLength":16,"title":"Platform","default":"android"}},"type":"object","required":["token"],"title":"DeviceIn"},"DeviceOut":{"properties":{"id":{"type":"integer","title":"Id"},"platform":{"type":"string","title":"Platform"},"active":{"type":"boolean","title":"Active"}},"type":"object","required":["id","platform","active"],"title":"DeviceOut"},"DeviceTokenIn":{"properties":{"token":{"type":"string","maxLength":256,"minLength":8,"title":"Token"},"platform":{"type":"string","title":"Platform","default":"android"}},"type":"object","required":["token"],"title":"DeviceTokenIn"},"DiagnosticsIn":{"properties":{"location":{"type":"string","title":"Location"}},"type":"object","required":["location"],"title":"DiagnosticsIn"},"DisplayMessageIn":{"properties":{"content":{"type":"string","title":"Content"},"priority":{"type":"string","title":"Priority","default":"NormalCycle"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"message_id":{"type":"integer","title":"Message Id","default":1}},"type":"object","required":["content"],"title":"DisplayMessageIn"},"FeedbackIn":{"properties":{"message":{"type":"string","maxLength":4000,"minLength":3,"title":"Message"},"kind":{"type":"string","title":"Kind","default":"other"},"contact_email":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Contact Email"},"app_version":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"App Version"},"platform":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Platform"},"device":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Device"}},"type":"object","required":["message"],"title":"FeedbackIn"},"GetLogIn":{"properties":{"remote_location":{"type":"string","title":"Remote Location"},"log_type":{"type":"string","title":"Log Type","default":"DiagnosticsLog"}},"type":"object","required":["remote_location"],"title":"GetLogIn"},"GetVariablesIn":{"properties":{"variables":{"items":{"$ref":"#/components/schemas/VariableRefIn"},"type":"array","title":"Variables"}},"type":"object","required":["variables"],"title":"GetVariablesIn"},"GroupCreate":{"properties":{"name":{"type":"string","maxLength":120,"minLength":1,"title":"Name"},"kind":{"type":"string","pattern":"^(family|team)$","title":"Kind","default":"family"}},"type":"object","required":["name"],"title":"GroupCreate"},"GroupUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":120,"minLength":1},{"type":"null"}],"title":"Name"},"pays_for_members":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Pays For Members"},"auto_topup_below":{"anyOf":[{"type":"number","maximum":10000000.0,"minimum":0.0},{"type":"null"}],"title":"Auto Topup Below"},"auto_topup_amount":{"anyOf":[{"type":"number","maximum":10000000.0,"minimum":1.0},{"type":"null"}],"title":"Auto Topup Amount"},"clear_auto_topup":{"type":"boolean","title":"Clear Auto Topup","default":false}},"type":"object","title":"GroupUpdate"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HeartbeatIn":{"properties":{"firmware":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Firmware"},"playlist_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Playlist Version"}},"type":"object","title":"HeartbeatIn"},"HostChargerCreate":{"properties":{"ocpp_identity":{"type":"string","maxLength":64,"minLength":1,"title":"Ocpp Identity"},"connector_type":{"type":"string","maxLength":20,"title":"Connector Type","default":"CCS2"},"power_kw":{"type":"integer","maximum":1000.0,"minimum":0.0,"title":"Power Kw","default":22}},"type":"object","required":["ocpp_identity"],"title":"HostChargerCreate"},"HostChargerOut":{"properties":{"id":{"type":"integer","title":"Id"},"ocpp_identity":{"type":"string","title":"Ocpp Identity"},"name":{"type":"string","title":"Name"},"online":{"type":"boolean","title":"Online","default":false}},"type":"object","required":["id","ocpp_identity","name"],"title":"HostChargerOut"},"HostMetrics":{"properties":{"energy_kwh":{"type":"number","title":"Energy Kwh"},"sessions":{"type":"integer","title":"Sessions"},"users":{"type":"integer","title":"Users"},"revenue":{"type":"number","title":"Revenue"}},"type":"object","required":["energy_kwh","sessions","users","revenue"],"title":"HostMetrics"},"HostOverviewOut":{"properties":{"stations":{"type":"integer","title":"Stations"},"chargers":{"type":"integer","title":"Chargers"},"currency":{"type":"string","title":"Currency"},"today":{"$ref":"#/components/schemas/HostMetrics"},"total":{"$ref":"#/components/schemas/HostMetrics"}},"type":"object","required":["stations","chargers","currency","today","total"],"title":"HostOverviewOut"},"HostSessionOut":{"properties":{"id":{"type":"integer","title":"Id"},"station_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Station Id"},"station_name":{"type":"string","title":"Station Name"},"connector_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connector Name"},"energy_kwh":{"type":"number","title":"Energy Kwh"},"meter_start_wh":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Meter Start Wh"},"meter_stop_wh":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Meter Stop Wh"},"meter_baselined":{"type":"boolean","title":"Meter Baselined"},"price_per_kwh":{"type":"number","title":"Price Per Kwh"},"cost":{"type":"number","title":"Cost"},"currency":{"type":"string","title":"Currency"},"duration_minutes":{"type":"integer","title":"Duration Minutes"},"payment_method":{"type":"string","title":"Payment Method"},"payment_state":{"type":"string","title":"Payment State"},"completed_at":{"type":"string","title":"Completed At"},"finalised_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finalised By"}},"type":"object","required":["id","station_id","station_name","connector_name","energy_kwh","meter_baselined","price_per_kwh","cost","currency","duration_minutes","payment_method","payment_state","completed_at"],"title":"HostSessionOut","description":"One charge, as the operator who owns the charger is allowed to see it.\n\nDeliberately **not** `SessionOut`. That schema is the driver's own receipt\nand carries `vehicle_id` and `paid_by_group_id` — an operator has no\nbusiness knowing which car arrived or whose family wallet paid, and the\ncount of distinct drivers on the overview is the most identity this side of\nthe product needs. Under the DPDP Act the test is necessity, and the\noperator's necessity stops at \"what did this charger deliver, and was it\npaid for\".\n\nWhat is kept is everything a billing dispute turns on: the meter pair, what\nended the session, and whether the money arrived."},"HostStationCreate":{"properties":{"name":{"type":"string","maxLength":160,"minLength":1,"title":"Name"},"address":{"type":"string","maxLength":255,"minLength":1,"title":"Address"},"latitude":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Latitude"},"longitude":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Longitude"},"price_per_kwh":{"type":"number","minimum":0.0,"title":"Price Per Kwh","default":0},"currency":{"type":"string","maxLength":3,"title":"Currency","default":"INR"},"type":{"type":"string","maxLength":20,"title":"Type","default":"commercial"},"chargers":{"items":{"$ref":"#/components/schemas/HostChargerCreate"},"type":"array","title":"Chargers"}},"type":"object","required":["name","address","latitude","longitude"],"title":"HostStationCreate"},"HostStationOut":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"address":{"type":"string","title":"Address"},"latitude":{"type":"number","title":"Latitude"},"longitude":{"type":"number","title":"Longitude"},"price_per_kwh":{"type":"number","title":"Price Per Kwh"},"currency":{"type":"string","title":"Currency"},"type":{"type":"string","title":"Type"},"status":{"type":"string","title":"Status"},"connectors":{"items":{"$ref":"#/components/schemas/ConnectorOut"},"type":"array","title":"Connectors"},"chargers":{"items":{"$ref":"#/components/schemas/HostChargerOut"},"type":"array","title":"Chargers"}},"type":"object","required":["id","name","address","latitude","longitude","price_per_kwh","currency","type","status","connectors","chargers"],"title":"HostStationOut"},"IntentIn":{"properties":{"ocpp_identity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocpp Identity"},"pay_with":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pay With"},"vehicle_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Vehicle Id"},"start_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Start Percent"},"authorised_amount":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Authorised Amount"},"order_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Order Id"},"connector_id":{"anyOf":[{"type":"integer","maximum":64.0,"minimum":1.0},{"type":"null"}],"title":"Connector Id"},"target_kwh":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Target Kwh"}},"type":"object","title":"IntentIn","description":"What the driver chose, before the charge exists."},"InternalSessionIn":{"properties":{"station_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Station Id"},"station_name":{"type":"string","maxLength":160,"minLength":1,"title":"Station Name"},"connector_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connector Name"},"power_kw":{"type":"integer","minimum":0.0,"title":"Power Kw","default":0},"energy_kwh":{"type":"number","minimum":0.0,"title":"Energy Kwh","default":0.0},"price_per_kwh":{"type":"number","minimum":0.0,"title":"Price Per Kwh","default":0.0},"cost":{"type":"number","minimum":0.0,"title":"Cost","default":0.0},"currency":{"type":"string","title":"Currency","default":"INR"},"start_percent":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Start Percent","default":0.0},"end_percent":{"type":"number","maximum":100.0,"minimum":0.0,"title":"End Percent","default":0.0},"duration_minutes":{"type":"integer","minimum":0.0,"title":"Duration Minutes","default":0},"payment_method":{"type":"string","title":"Payment Method","default":"Wallet"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"external_id":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"External Id"},"price_breakdown":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Price Breakdown"},"stop_reason":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Stop Reason"},"vehicle_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Vehicle Id"},"meter_start_wh":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Meter Start Wh"},"meter_stop_wh":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Meter Stop Wh"},"meter_baselined":{"type":"boolean","title":"Meter Baselined","default":false},"pay_with":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Pay With"},"ocpp_identity":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Ocpp Identity"},"connector_id":{"anyOf":[{"type":"integer","maximum":64.0,"minimum":0.0},{"type":"null"}],"title":"Connector Id"},"finalised_by":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Finalised By"},"authorised_amount":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Authorised Amount"},"user_ref":{"type":"string","title":"User Ref"}},"type":"object","required":["station_name","user_ref"],"title":"InternalSessionIn"},"InviteCreate":{"properties":{"label":{"anyOf":[{"type":"string","maxLength":60},{"type":"null"}],"title":"Label"},"role":{"type":"string","title":"Role","default":"member"},"monthly_limit":{"anyOf":[{"type":"number","maximum":10000000.0,"minimum":0.0},{"type":"null"}],"title":"Monthly Limit"},"vehicle_ids":{"items":{"type":"integer"},"type":"array","maxItems":25,"title":"Vehicle Ids"},"max_uses":{"type":"integer","maximum":25.0,"minimum":1.0,"title":"Max Uses","default":1},"expires_in_hours":{"anyOf":[{"type":"integer","maximum":336.0,"minimum":1.0},{"type":"null"}],"title":"Expires In Hours"}},"type":"object","title":"InviteCreate","description":"What an invitation decides in advance.\n\nEvery field has a default that reproduces the old behaviour exactly — a\nsingle-use, seven-day, plain-member invite — so an older app that posts an\nempty body keeps working and gets the safe end of every choice."},"InviteIn":{"properties":{"email":{"type":"string","maxLength":255,"minLength":3,"title":"Email"},"role":{"type":"string","pattern":"^(admin|viewer)$","title":"Role","default":"viewer"}},"type":"object","required":["email"],"title":"InviteIn"},"JoinIn":{"properties":{"ocpp_identity":{"type":"string","title":"Ocpp Identity"},"connector_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Connector Id"}},"type":"object","required":["ocpp_identity"],"title":"JoinIn"},"JoinRequest":{"properties":{"code":{"type":"string","maxLength":12,"minLength":4,"title":"Code"}},"type":"object","required":["code"],"title":"JoinRequest"},"LatLngIn":{"properties":{"lat":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Lat"},"lng":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Lng"}},"type":"object","required":["lat","lng"],"title":"LatLngIn"},"MarkPaidIn":{"properties":{"payout_id":{"type":"integer","title":"Payout Id"},"payment_reference":{"type":"string","maxLength":120,"minLength":1,"title":"Payment Reference"}},"type":"object","required":["payout_id","payment_reference"],"title":"MarkPaidIn"},"MeOut":{"properties":{"id":{"type":"integer","title":"Id"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"role":{"type":"string","title":"Role"},"provider":{"type":"string","title":"Provider"},"kyc_status":{"type":"string","title":"Kyc Status"},"wallet_balance":{"type":"number","title":"Wallet Balance"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gender"},"date_of_birth":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date Of Birth"},"vehicles":{"items":{"$ref":"#/components/schemas/VehicleOut"},"type":"array","title":"Vehicles","default":[]},"unpaid_total":{"type":"number","title":"Unpaid Total","default":0.0},"deficit_total":{"type":"number","title":"Deficit Total","default":0.0},"refund_destination":{"type":"string","title":"Refund Destination","default":"bank"},"can_start_charge":{"type":"boolean","title":"Can Start Charge","default":true},"blocked_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Blocked Reason"}},"type":"object","required":["id","phone","email","name","role","provider","kyc_status","wallet_balance"],"title":"MeOut"},"MemberUpdate":{"properties":{"role":{"anyOf":[{"type":"string","pattern":"^(admin|member)$"},{"type":"null"}],"title":"Role"},"monthly_limit":{"anyOf":[{"type":"number","maximum":10000000.0,"minimum":0.0},{"type":"null"}],"title":"Monthly Limit"},"clear_limit":{"type":"boolean","title":"Clear Limit","default":false}},"type":"object","title":"MemberUpdate"},"ModerationDecision":{"properties":{"approve":{"type":"boolean","title":"Approve"},"note":{"type":"string","maxLength":500,"title":"Note","default":""}},"type":"object","required":["approve"],"title":"ModerationDecision"},"MonitorIn":{"properties":{"component":{"type":"string","title":"Component","default":"Connector"},"variable":{"type":"string","title":"Variable"},"type":{"type":"string","title":"Type","default":"UpperThreshold"},"value":{"type":"number","title":"Value"},"severity":{"type":"integer","title":"Severity","default":5}},"type":"object","required":["variable","value"],"title":"MonitorIn"},"MonitoringBaseIn":{"properties":{"base":{"type":"string","title":"Base","default":"All"}},"type":"object","title":"MonitoringBaseIn"},"OcpiPartyIn":{"properties":{"country_code":{"type":"string","maxLength":2,"minLength":2,"title":"Country Code"},"party_id":{"type":"string","maxLength":3,"minLength":3,"title":"Party Id"},"name":{"type":"string","title":"Name","default":""},"role":{"type":"string","title":"Role","default":"EMSP"},"versions_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Versions Url"},"token_out":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token Out"}},"type":"object","required":["country_code","party_id"],"title":"OcpiPartyIn"},"OrderRequest":{"properties":{"amount":{"type":"number","maximum":100000.0,"exclusiveMinimum":9.0,"title":"Amount"}},"type":"object","required":["amount"],"title":"OrderRequest"},"PartnerCreate":{"properties":{"name":{"type":"string","maxLength":160,"minLength":1,"title":"Name"},"email":{"type":"string","format":"email","title":"Email"},"mobile":{"type":"string","maxLength":32,"minLength":1,"title":"Mobile"},"city":{"type":"string","maxLength":120,"minLength":1,"title":"City"},"state":{"type":"string","maxLength":120,"minLength":1,"title":"State"}},"type":"object","required":["name","email","mobile","city","state"],"title":"PartnerCreate"},"PartnerResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"},"mobile":{"type":"string","title":"Mobile"},"city":{"type":"string","title":"City"},"state":{"type":"string","title":"State"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","name","email","mobile","city","state","status","created_at"],"title":"PartnerResponse"},"PayForChargeOut":{"properties":{"order_id":{"type":"string","title":"Order Id"},"amount":{"type":"number","title":"Amount"},"currency":{"type":"string","title":"Currency","default":"INR"},"key_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"},"session_id":{"type":"integer","title":"Session Id"},"already_paid":{"type":"boolean","title":"Already Paid","default":false}},"type":"object","required":["order_id","amount","session_id"],"title":"PayForChargeOut","description":"An order the driver can settle a finished charge with."},"PaymentIntentIn":{"properties":{"amount":{"type":"number","exclusiveMinimum":0.0,"title":"Amount"},"connector_id":{"type":"integer","title":"Connector Id","default":1},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"push_to_charger":{"type":"boolean","title":"Push To Charger","default":true}},"type":"object","required":["amount"],"title":"PaymentIntentIn"},"PlateKind":{"type":"string","enum":["standard","bh","temporary","exempt","applied"],"title":"PlateKind"},"PlayIn":{"properties":{"creative_id":{"type":"integer","title":"Creative Id"},"campaign_id":{"type":"integer","title":"Campaign Id"},"started_at":{"type":"string","format":"date-time","title":"Started At"},"duration_ms":{"type":"integer","minimum":0.0,"title":"Duration Ms"},"completed":{"type":"boolean","title":"Completed","default":true},"session_active":{"type":"boolean","title":"Session Active","default":false},"idempotency_key":{"type":"string","maxLength":128,"minLength":8,"title":"Idempotency Key"}},"type":"object","required":["creative_id","campaign_id","started_at","duration_ms","idempotency_key"],"title":"PlayIn"},"PlugIn":{"properties":{"ocpp_identity":{"type":"string","maxLength":64,"minLength":1,"title":"Ocpp Identity"},"connector_id":{"type":"integer","maximum":64.0,"minimum":0.0,"title":"Connector Id","default":1},"station_id":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Station Id"},"evccid":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Evccid"},"plugged":{"type":"boolean","title":"Plugged","default":true}},"type":"object","required":["ocpp_identity"],"title":"PlugIn","description":"What the CSMS saw when a connector moved to `Preparing`.\n\n`evccid` is present only where the charger does Autocharge — it reads the\nvehicle's communication-controller MAC off the ISO 15118 / DIN 70121\nhandshake. Most chargers do not, which is why every field but the identity\nis optional and the feature degrades to \"somebody plugged something in\nhere\" rather than failing."},"PreferencesIn":{"properties":{"charge_complete":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Charge Complete"},"charge_interrupted":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Charge Interrupted"},"station_alerts":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Station Alerts"},"trip_alerts":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Trip Alerts"},"charging_slowed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Charging Slowed"},"move_your_vehicle":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Move Your Vehicle"}},"type":"object","title":"PreferencesIn","description":"A partial update: omitted categories are left alone.\n\nAll-optional rather than all-required so a client built against an older\nversion of this API cannot silently reset a category it has never heard of\nback to its default."},"ProblemIn":{"properties":{"kind":{"type":"string","title":"Kind"},"connector_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connector Name"},"note":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Note"},"transaction_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Transaction Id"},"ocpp_identity":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Ocpp Identity"}},"type":"object","required":["kind"],"title":"ProblemIn"},"QueuedCommandIn":{"properties":{"queue_id":{"type":"integer","title":"Queue Id"}},"type":"object","required":["queue_id"],"title":"QueuedCommandIn"},"QuoteRequest":{"properties":{"station_id":{"type":"string","maxLength":64,"minLength":1,"title":"Station Id"},"connector_id":{"type":"integer","maximum":16.0,"minimum":1.0,"title":"Connector Id","default":1},"amount":{"type":"number","maximum":10000.0,"exclusiveMinimum":49.0,"title":"Amount"}},"type":"object","required":["station_id","amount"],"title":"QuoteRequest"},"RegisterRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Name"},"phone":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Phone"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"}},"type":"object","title":"RegisterRequest","description":"Called by the app right after Firebase sign-in. The bearer token\nidentifies the user; these optional fields fill in the profile (useful in\nmock mode where the token carries no claims)."},"RemainderOut":{"properties":{"session_id":{"type":"integer","title":"Session Id"},"authorised":{"type":"number","title":"Authorised"},"billed":{"type":"number","title":"Billed"},"remaining":{"type":"number","title":"Remaining"},"currency":{"type":"string","title":"Currency","default":"INR"},"settled":{"type":"boolean","title":"Settled"}},"type":"object","required":["session_id","authorised","billed","remaining","settled"],"title":"RemainderOut","description":"What is left of the money secured for one charge."},"ReplayIn":{"properties":{"transaction_id":{"type":"string","title":"Transaction Id"}},"type":"object","required":["transaction_id"],"title":"ReplayIn"},"ReserveIn":{"properties":{"ocpp_identity":{"type":"string","title":"Ocpp Identity"},"connector_id":{"type":"integer","maximum":16.0,"minimum":1.0,"title":"Connector Id","default":1},"minutes":{"type":"integer","maximum":30.0,"minimum":5.0,"title":"Minutes","default":15},"starts_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Starts At"},"pay_with":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pay With"}},"type":"object","required":["ocpp_identity"],"title":"ReserveIn"},"ResetIn":{"properties":{"type":{"type":"string","title":"Type","default":"Soft"}},"type":"object","title":"ResetIn"},"RetryDeliveriesIn":{"properties":{"dedupe_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dedupe Key"},"all_dead":{"type":"boolean","title":"All Dead","default":false}},"type":"object","title":"RetryDeliveriesIn"},"ReturnRemainderIn":{"properties":{"destination":{"type":"string","pattern":"^(wallet|bank)$","title":"Destination","default":"wallet"}},"type":"object","title":"ReturnRemainderIn","description":"Where the unused part of a prepayment should go."},"ReturnRemainderOut":{"properties":{"returned":{"type":"number","title":"Returned"},"destination":{"type":"string","title":"Destination"},"currency":{"type":"string","title":"Currency","default":"INR"},"detail":{"type":"string","title":"Detail"}},"type":"object","required":["returned","destination","detail"],"title":"ReturnRemainderOut"},"ReviewIn":{"properties":{"session_id":{"type":"integer","title":"Session Id"},"rating":{"type":"integer","maximum":5.0,"minimum":1.0,"title":"Rating"},"worked":{"type":"string","title":"Worked","default":"yes"},"body":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Body"},"photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Photo Url"}},"type":"object","required":["session_id","rating"],"title":"ReviewIn"},"RoamingAuthorizeIn":{"properties":{"token_uid":{"type":"string","maxLength":64,"minLength":1,"title":"Token Uid"}},"type":"object","required":["token_uid"],"title":"RoamingAuthorizeIn"},"RoamingEnquiryCreate":{"properties":{"company":{"type":"string","maxLength":160,"minLength":1,"title":"Company"},"countryCode":{"type":"string","maxLength":2,"minLength":2,"title":"Countrycode"},"partyId":{"type":"string","maxLength":3,"minLength":3,"title":"Partyid"},"role":{"type":"string","title":"Role","default":"CPO"},"contactName":{"type":"string","title":"Contactname","default":""},"email":{"type":"string","format":"email","title":"Email"},"versionsUrl":{"type":"string","title":"Versionsurl","default":""},"notes":{"type":"string","title":"Notes","default":""}},"type":"object","required":["company","countryCode","partyId","email"],"title":"RoamingEnquiryCreate"},"RoamingEnquiryResponse":{"properties":{"id":{"type":"integer","title":"Id"},"company":{"type":"string","title":"Company"},"country_code":{"type":"string","title":"Country Code"},"party_id":{"type":"string","title":"Party Id"},"role":{"type":"string","title":"Role"},"email":{"type":"string","title":"Email"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","company","country_code","party_id","role","email","status","created_at"],"title":"RoamingEnquiryResponse"},"RoamingSessionIn":{"properties":{"id":{"type":"integer","title":"Id"},"party":{"type":"string","title":"Party","default":""},"user_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Ref"},"location_id":{"type":"string","title":"Location Id","default":""},"evse_uid":{"type":"string","title":"Evse Uid","default":""},"energy_kwh":{"type":"number","title":"Energy Kwh","default":0.0},"partner_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Partner Cost"},"driver_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Driver Cost"},"currency":{"type":"string","title":"Currency","default":"INR"}},"type":"object","required":["id"],"title":"RoamingSessionIn","description":"A completed roaming charge, as the CSMS holds it."},"RoamingStartIn":{"properties":{"station_id":{"type":"string","title":"Station Id"},"evse_uid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Evse Uid"}},"type":"object","required":["station_id"],"title":"RoamingStartIn"},"RoamingStopIn":{"properties":{"roaming_session_id":{"type":"integer","title":"Roaming Session Id"}},"type":"object","required":["roaming_session_id"],"title":"RoamingStopIn"},"RouteOut":{"properties":{"label":{"type":"string","title":"Label"},"summary":{"type":"string","title":"Summary"},"distance_km":{"type":"number","title":"Distance Km"},"drive_minutes":{"type":"integer","title":"Drive Minutes"},"charge_minutes":{"type":"integer","title":"Charge Minutes"},"total_minutes":{"type":"integer","title":"Total Minutes"},"encoded_polyline":{"type":"string","title":"Encoded Polyline"},"stops":{"items":{"$ref":"#/components/schemas/ChargeStopOut"},"type":"array","title":"Stops"},"feasible":{"type":"boolean","title":"Feasible"},"chargers":{"items":{"$ref":"#/components/schemas/CorridorChargerOut"},"type":"array","title":"Chargers"},"total_energy_kwh":{"type":"number","title":"Total Energy Kwh","default":0.0},"consumption_kwh_per_100km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Consumption Kwh Per 100Km"},"consumption_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consumption Note"},"minutes_vs_fastest":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Minutes Vs Fastest"},"cost_vs_fastest":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost Vs Fastest"},"trade_off":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trade Off"},"known_cost":{"type":"number","title":"Known Cost","default":0.0},"unpriced_stops":{"type":"integer","title":"Unpriced Stops","default":0}},"type":"object","required":["label","summary","distance_km","drive_minutes","charge_minutes","total_minutes","encoded_polyline","stops","feasible"],"title":"RouteOut"},"SessionCreate":{"properties":{"station_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Station Id"},"station_name":{"type":"string","maxLength":160,"minLength":1,"title":"Station Name"},"connector_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connector Name"},"power_kw":{"type":"integer","minimum":0.0,"title":"Power Kw","default":0},"energy_kwh":{"type":"number","minimum":0.0,"title":"Energy Kwh","default":0.0},"price_per_kwh":{"type":"number","minimum":0.0,"title":"Price Per Kwh","default":0.0},"cost":{"type":"number","minimum":0.0,"title":"Cost","default":0.0},"currency":{"type":"string","title":"Currency","default":"INR"},"start_percent":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Start Percent","default":0.0},"end_percent":{"type":"number","maximum":100.0,"minimum":0.0,"title":"End Percent","default":0.0},"duration_minutes":{"type":"integer","minimum":0.0,"title":"Duration Minutes","default":0},"payment_method":{"type":"string","title":"Payment Method","default":"Wallet"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"external_id":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"External Id"},"price_breakdown":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Price Breakdown"},"stop_reason":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Stop Reason"},"vehicle_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Vehicle Id"},"meter_start_wh":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Meter Start Wh"},"meter_stop_wh":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Meter Stop Wh"},"meter_baselined":{"type":"boolean","title":"Meter Baselined","default":false},"pay_with":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Pay With"},"ocpp_identity":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Ocpp Identity"},"connector_id":{"anyOf":[{"type":"integer","maximum":64.0,"minimum":0.0},{"type":"null"}],"title":"Connector Id"},"finalised_by":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Finalised By"},"authorised_amount":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Authorised Amount"}},"type":"object","required":["station_name"],"title":"SessionCreate"},"SessionOut":{"properties":{"id":{"type":"integer","title":"Id"},"station_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Station Id"},"station_name":{"type":"string","title":"Station Name"},"connector_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connector Name"},"power_kw":{"type":"integer","title":"Power Kw"},"energy_kwh":{"type":"number","title":"Energy Kwh"},"meter_start_wh":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Meter Start Wh"},"meter_stop_wh":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Meter Stop Wh"},"meter_baselined":{"type":"boolean","title":"Meter Baselined"},"price_per_kwh":{"type":"number","title":"Price Per Kwh"},"cost":{"type":"number","title":"Cost"},"currency":{"type":"string","title":"Currency"},"start_percent":{"type":"number","title":"Start Percent"},"end_percent":{"type":"number","title":"End Percent"},"duration_minutes":{"type":"integer","title":"Duration Minutes"},"payment_method":{"type":"string","title":"Payment Method"},"completed_at":{"type":"string","title":"Completed At"},"external_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Id"},"price_breakdown":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Price Breakdown"},"paid_by_group_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paid By Group Id"},"payment_state":{"type":"string","title":"Payment State"},"vehicle_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Vehicle Id"},"authorised_amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Authorised Amount"},"finalised_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finalised By"},"min_fee_applied":{"type":"boolean","title":"Min Fee Applied"}},"type":"object","required":["id","station_id","station_name","connector_name","power_kw","energy_kwh","meter_baselined","price_per_kwh","cost","currency","start_percent","end_percent","duration_minutes","payment_method","completed_at","payment_state","min_fee_applied"],"title":"SessionOut"},"SetMonitoringIn":{"properties":{"monitors":{"items":{"$ref":"#/components/schemas/MonitorIn"},"type":"array","title":"Monitors"}},"type":"object","required":["monitors"],"title":"SetMonitoringIn"},"SetVariablesIn":{"properties":{"variables":{"items":{"$ref":"#/components/schemas/VariableSetIn"},"type":"array","title":"Variables"}},"type":"object","required":["variables"],"title":"SetVariablesIn"},"SettleDeficitsOut":{"properties":{"applied":{"type":"number","title":"Applied"},"outstanding":{"type":"number","title":"Outstanding"},"currency":{"type":"string","title":"Currency","default":"INR"},"can_start_charge":{"type":"boolean","title":"Can Start Charge"}},"type":"object","required":["applied","outstanding","can_start_charge"],"title":"SettleDeficitsOut"},"SettleIn":{"properties":{"pay_with":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pay With"}},"type":"object","title":"SettleIn","description":"Which wallet to settle an unpaid charge from."},"ShareVehicle":{"properties":{"vehicle_id":{"type":"integer","title":"Vehicle Id"},"restricted":{"type":"boolean","title":"Restricted","default":false},"member_ids":{"items":{"type":"integer"},"type":"array","maxItems":50,"title":"Member Ids"}},"type":"object","required":["vehicle_id"],"title":"ShareVehicle"},"SiteIn":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"circuit_limit_kw":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Circuit Limit Kw"},"circuit_limit_a":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Circuit Limit A"},"phases":{"anyOf":[{"type":"integer","maximum":3.0,"minimum":1.0},{"type":"null"}],"title":"Phases"},"voltage":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Voltage"},"reserved_kw":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Reserved Kw"},"min_charge_kw":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Min Charge Kw"},"tariff_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tariff Id"},"allocation_strategy":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Allocation Strategy"},"load_management_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Load Management Enabled"},"dg_limit_kw":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Dg Limit Kw"},"solar_priority":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Solar Priority"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timezone"}},"type":"object","required":["id","name"],"title":"SiteIn"},"SmartChargingIn":{"properties":{"connector_id":{"type":"integer","title":"Connector Id","default":1},"mode":{"type":"string","title":"Mode","default":"cap"},"limit_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Limit Kw"},"start_hour":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Start Hour"},"end_hour":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"End Hour"},"amps":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Amps"},"number_phases":{"type":"integer","title":"Number Phases","default":3}},"type":"object","title":"SmartChargingIn"},"StartRequest":{"properties":{"station_id":{"type":"string","maxLength":64,"minLength":1,"title":"Station Id"},"connector_id":{"type":"integer","maximum":16.0,"minimum":1.0,"title":"Connector Id","default":1},"amount":{"type":"number","maximum":10000.0,"exclusiveMinimum":49.0,"title":"Amount"},"contact":{"anyOf":[{"type":"string","maxLength":160},{"type":"null"}],"title":"Contact"}},"type":"object","required":["station_id","amount"],"title":"StartRequest"},"StationDetail":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"address":{"type":"string","title":"Address"},"latitude":{"type":"number","title":"Latitude"},"longitude":{"type":"number","title":"Longitude"},"available":{"type":"integer","title":"Available"},"total":{"type":"integer","title":"Total"},"max_power_kw":{"type":"integer","title":"Max Power Kw"},"price_per_kwh":{"type":"number","title":"Price Per Kwh"},"currency":{"type":"string","title":"Currency"},"connector_types":{"items":{"type":"string"},"type":"array","title":"Connector Types"},"amenities":{"items":{"type":"string"},"type":"array","title":"Amenities"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"distance_km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Distance Km"},"source":{"type":"string","title":"Source","default":"network"},"network":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Network"},"price_known":{"type":"boolean","title":"Price Known","default":true},"reliability":{"anyOf":[{"$ref":"#/components/schemas/StationReliabilityOut"},{"type":"null"}]},"type":{"type":"string","title":"Type"},"status":{"type":"string","title":"Status"},"usable":{"type":"boolean","title":"Usable"},"connectors":{"items":{"$ref":"#/components/schemas/ConnectorOut"},"type":"array","title":"Connectors"},"ocpp_identity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ocpp Identity"},"score":{"anyOf":[{"$ref":"#/components/schemas/StationScoreOut"},{"type":"null"}]}},"type":"object","required":["id","name","address","latitude","longitude","available","total","max_power_kw","price_per_kwh","currency","connector_types","amenities","type","status","usable","connectors"],"title":"StationDetail"},"StationReliabilityOut":{"properties":{"worked_rate":{"type":"number","title":"Worked Rate"},"sample":{"type":"integer","title":"Sample"},"open_faults":{"type":"integer","title":"Open Faults"},"confident":{"type":"boolean","title":"Confident"}},"type":"object","required":["worked_rate","sample","open_faults","confident"],"title":"StationReliabilityOut","description":"Whether this charger actually works, from the people who tried.\n\nThis is the one thing we can tell a driver that nobody else in India can,\nand until now it was computed on every request and shown only to\noperators. The driver deciding where to drive never saw it."},"StationScoreOut":{"properties":{"total":{"type":"integer","title":"Total"},"reliability":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reliability"},"power":{"type":"integer","title":"Power"},"availability":{"type":"integer","title":"Availability"},"price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Price"}},"type":"object","required":["total","power","availability"],"title":"StationScoreOut","description":"Why the score is what it is.\n\nReturned in full rather than as a bare number: a driver who cannot see\nwhich part dragged it down has no reason to believe it the second time it\ndisagrees with them."},"StationSummary":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"address":{"type":"string","title":"Address"},"latitude":{"type":"number","title":"Latitude"},"longitude":{"type":"number","title":"Longitude"},"available":{"type":"integer","title":"Available"},"total":{"type":"integer","title":"Total"},"max_power_kw":{"type":"integer","title":"Max Power Kw"},"price_per_kwh":{"type":"number","title":"Price Per Kwh"},"currency":{"type":"string","title":"Currency"},"connector_types":{"items":{"type":"string"},"type":"array","title":"Connector Types"},"amenities":{"items":{"type":"string"},"type":"array","title":"Amenities"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"distance_km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Distance Km"},"source":{"type":"string","title":"Source","default":"network"},"network":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Network"},"price_known":{"type":"boolean","title":"Price Known","default":true},"reliability":{"anyOf":[{"$ref":"#/components/schemas/StationReliabilityOut"},{"type":"null"}]}},"type":"object","required":["id","name","address","latitude","longitude","available","total","max_power_kw","price_per_kwh","currency","connector_types","amenities"],"title":"StationSummary","description":"Card-level station data for the map + nearby list."},"TargetIn":{"properties":{"station_id":{"type":"string","title":"Station Id"},"day_of_week":{"anyOf":[{"type":"integer","maximum":6.0,"minimum":0.0},{"type":"null"}],"title":"Day Of Week"},"start_time":{"type":"string","title":"Start Time","default":"00:00"},"end_time":{"type":"string","title":"End Time","default":"23:59"},"requires_active_session":{"type":"boolean","title":"Requires Active Session","default":false}},"type":"object","required":["station_id"],"title":"TargetIn","description":"Site and time only. There is no driver field and adding one would need\na privacy-policy change, not a schema change."},"TariffIn":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"currency":{"type":"string","title":"Currency","default":"INR"},"base_price_per_kwh":{"type":"number","minimum":0.0,"title":"Base Price Per Kwh","default":0.0},"connection_fee":{"type":"number","minimum":0.0,"title":"Connection Fee","default":0.0},"time_price_per_minute":{"type":"number","minimum":0.0,"title":"Time Price Per Minute","default":0.0},"idle_fee_per_minute":{"type":"number","minimum":0.0,"title":"Idle Fee Per Minute","default":0.0},"idle_grace_minutes":{"type":"integer","minimum":0.0,"title":"Idle Grace Minutes","default":10},"tax_percent":{"type":"number","minimum":0.0,"title":"Tax Percent","default":0.0},"tax_inclusive":{"type":"boolean","title":"Tax Inclusive","default":false},"min_charge":{"type":"number","minimum":0.0,"title":"Min Charge","default":0.0},"time_of_day":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Time Of Day"}},"type":"object","required":["id","name"],"title":"TariffIn"},"TelemetryIn":{"properties":{"site_id":{"type":"string","title":"Site Id"},"solar_kw":{"type":"number","title":"Solar Kw","default":0.0},"grid_kw":{"type":"number","title":"Grid Kw","default":0.0},"building_kw":{"type":"number","title":"Building Kw","default":0.0},"battery_soc":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Battery Soc"},"on_generator":{"type":"boolean","title":"On Generator","default":false}},"type":"object","required":["site_id"],"title":"TelemetryIn"},"TransferOwnership":{"properties":{"member_id":{"type":"integer","title":"Member Id"}},"type":"object","required":["member_id"],"title":"TransferOwnership"},"TriggerIn":{"properties":{"requested_message":{"type":"string","title":"Requested Message","default":"StatusNotification"},"connector_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Connector Id"}},"type":"object","title":"TriggerIn"},"TripPlanIn":{"properties":{"origin":{"$ref":"#/components/schemas/LatLngIn"},"destination":{"$ref":"#/components/schemas/LatLngIn"},"intermediates":{"items":{"$ref":"#/components/schemas/LatLngIn"},"type":"array","maxItems":8,"title":"Intermediates"},"range_km":{"type":"number","maximum":2000.0,"exclusiveMinimum":1.0,"title":"Range Km","default":350},"start_soc":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Start Soc","default":80},"consumption_kwh_per_100km":{"type":"number","maximum":200.0,"exclusiveMinimum":1.0,"title":"Consumption Kwh Per 100Km","default":18.0},"battery_kwh":{"anyOf":[{"type":"number","maximum":1000.0,"exclusiveMinimum":1.0},{"type":"null"}],"title":"Battery Kwh"},"vehicle_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Vehicle Id"},"ambient_celsius":{"anyOf":[{"type":"number","maximum":60.0,"minimum":-30.0},{"type":"null"}],"title":"Ambient Celsius"},"mass_kg":{"type":"number","maximum":4000.0,"minimum":500.0,"title":"Mass Kg","default":1600},"max_charge_kw":{"type":"number","maximum":1000.0,"exclusiveMinimum":1.0,"title":"Max Charge Kw","default":60.0},"connectors":{"items":{"type":"string"},"type":"array","maxItems":8,"title":"Connectors"},"pinned_stop_ids":{"items":{"type":"string"},"type":"array","maxItems":10,"title":"Pinned Stop Ids"},"reserve_soc":{"type":"integer","maximum":50.0,"minimum":0.0,"title":"Reserve Soc","default":10},"target_soc":{"type":"integer","maximum":100.0,"minimum":30.0,"title":"Target Soc","default":80},"corridor_km":{"type":"number","maximum":40.0,"exclusiveMinimum":0.5,"title":"Corridor Km","default":12.0}},"type":"object","required":["origin","destination"],"title":"TripPlanIn"},"TripPlanOut":{"properties":{"routes":{"items":{"$ref":"#/components/schemas/RouteOut"},"type":"array","title":"Routes"}},"type":"object","required":["routes"],"title":"TripPlanOut"},"TripWatchIn":{"properties":{"station_ids":{"items":{"type":"string"},"type":"array","maxItems":12,"minItems":1,"title":"Station Ids"},"destination_label":{"type":"string","maxLength":160,"title":"Destination Label","default":""},"duration_minutes":{"type":"integer","maximum":1440.0,"minimum":5.0,"title":"Duration Minutes","default":240}},"type":"object","required":["station_ids"],"title":"TripWatchIn","description":"The route the driver actually took, not the ones they looked at."},"UnlockIn":{"properties":{"connector_id":{"type":"integer","title":"Connector Id","default":1}},"type":"object","title":"UnlockIn"},"UpdateFirmwareIn":{"properties":{"location":{"type":"string","title":"Location"},"retrieve_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Retrieve Date"}},"type":"object","required":["location"],"title":"UpdateFirmwareIn"},"UserUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Name"},"refund_destination":{"anyOf":[{"type":"string","pattern":"^(bank|wallet)$"},{"type":"null"}],"title":"Refund Destination"},"email":{"anyOf":[{"type":"string","maxLength":254},{"type":"null"}],"title":"Email"},"gender":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Gender"},"date_of_birth":{"anyOf":[{"type":"string","pattern":"^(\\d{4}-\\d{2}-\\d{2})?$"},{"type":"null"}],"title":"Date Of Birth"},"role":{"anyOf":[{"type":"string","pattern":"^(driver|host)$"},{"type":"null"}],"title":"Role"}},"type":"object","title":"UserUpdate"},"V2GCapabilityIn":{"properties":{"supports_v2g":{"type":"boolean","title":"Supports V2G","default":true},"max_discharge_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Discharge Kw"}},"type":"object","title":"V2GCapabilityIn"},"V2GDispatchIn":{"properties":{"ocpp_identity":{"type":"string","title":"Ocpp Identity"},"connector_id":{"type":"integer","title":"Connector Id","default":1},"kind":{"type":"string","title":"Kind","default":"peak_shave"},"requested_kw":{"type":"number","title":"Requested Kw","default":0.0},"duration_minutes":{"type":"integer","title":"Duration Minutes","default":30},"floor_soc":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Floor Soc"}},"type":"object","required":["ocpp_identity"],"title":"V2GDispatchIn"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VariableRefIn":{"properties":{"component":{"type":"string","title":"Component","default":"Charger"},"variable":{"type":"string","title":"Variable"},"attribute_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attribute Type"}},"type":"object","required":["variable"],"title":"VariableRefIn"},"VariableSetIn":{"properties":{"component":{"type":"string","title":"Component","default":"Charger"},"variable":{"type":"string","title":"Variable"},"attribute_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attribute Type"},"value":{"type":"string","title":"Value"}},"type":"object","required":["variable","value"],"title":"VariableSetIn"},"VehicleCatalogItem":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"battery_label":{"type":"string","title":"Battery Label"},"battery_kwh":{"type":"integer","title":"Battery Kwh"}},"type":"object","required":["id","name","battery_label","battery_kwh"],"title":"VehicleCatalogItem","description":"One of the preset models the app's vehicle-selection screen offers."},"VehicleCreate":{"properties":{"make":{"type":"string","maxLength":60,"minLength":1,"title":"Make"},"model":{"type":"string","maxLength":80,"minLength":1,"title":"Model"},"battery_kwh":{"type":"integer","maximum":500.0,"minimum":0.0,"title":"Battery Kwh","default":0},"connector_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connector Type"},"is_default":{"type":"boolean","title":"Is Default","default":false},"nickname":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Nickname"},"registration":{"anyOf":[{"type":"string","maxLength":24},{"type":"null"}],"title":"Registration"},"registration_kind":{"anyOf":[{"$ref":"#/components/schemas/PlateKind"},{"type":"null"}]},"autocharge_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Autocharge Enabled"},"autocharge_limit":{"anyOf":[{"type":"number","maximum":100000.0,"minimum":50.0},{"type":"null"}],"title":"Autocharge Limit"}},"type":"object","required":["make","model"],"title":"VehicleCreate"},"VehicleOut":{"properties":{"id":{"type":"integer","title":"Id"},"make":{"type":"string","title":"Make"},"model":{"type":"string","title":"Model"},"battery_kwh":{"type":"integer","title":"Battery Kwh"},"connector_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connector Type"},"is_default":{"type":"boolean","title":"Is Default"},"nickname":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nickname"},"autocharge_enabled":{"type":"boolean","title":"Autocharge Enabled","default":false},"autocharge_limit":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Autocharge Limit"},"registration":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Registration"},"registration_kind":{"type":"string","title":"Registration Kind","default":"applied"},"registration_expires_on":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Registration Expires On"},"registration_display":{"type":"string","title":"Registration Display","default":""},"plate_colour":{"type":"string","title":"Plate Colour","default":"none"}},"type":"object","required":["id","make","model","battery_kwh","connector_type","is_default"],"title":"VehicleOut"},"VehicleUpdate":{"properties":{"make":{"anyOf":[{"type":"string","maxLength":60,"minLength":1},{"type":"null"}],"title":"Make"},"model":{"anyOf":[{"type":"string","maxLength":80,"minLength":1},{"type":"null"}],"title":"Model"},"battery_kwh":{"anyOf":[{"type":"integer","maximum":1000.0,"minimum":0.0},{"type":"null"}],"title":"Battery Kwh"},"connector_type":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Connector Type"},"is_default":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Default"},"nickname":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Nickname"},"registration":{"anyOf":[{"type":"string","maxLength":24},{"type":"null"}],"title":"Registration"},"registration_kind":{"anyOf":[{"$ref":"#/components/schemas/PlateKind"},{"type":"null"}]},"autocharge_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Autocharge Enabled"},"autocharge_limit":{"anyOf":[{"type":"number","maximum":100000.0,"minimum":50.0},{"type":"null"}],"title":"Autocharge Limit"}},"type":"object","title":"VehicleUpdate","description":"Every field optional: this is a patch, and a driver fixing a typo in the\nmodel name should not have to resend the battery size to keep it."},"WaitlistCreate":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"WaitlistCreate"},"WaitlistResponse":{"properties":{"id":{"type":"integer","title":"Id"},"email":{"type":"string","title":"Email"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","email","created_at"],"title":"WaitlistResponse"},"WalletOut":{"properties":{"balance":{"type":"number","title":"Balance"},"currency":{"type":"string","title":"Currency","default":"INR"},"transactions":{"items":{"$ref":"#/components/schemas/WalletTransactionOut"},"type":"array","title":"Transactions","default":[]}},"type":"object","required":["balance"],"title":"WalletOut"},"WalletTransactionOut":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"amount":{"type":"number","title":"Amount"},"currency":{"type":"string","title":"Currency"},"kind":{"type":"string","title":"Kind"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","title","amount","currency","kind","created_at"],"title":"WalletTransactionOut"},"WithdrawRequest":{"properties":{"amount":{"type":"number","maximum":100000.0,"exclusiveMinimum":0.0,"title":"Amount"}},"type":"object","required":["amount"],"title":"WithdrawRequest","description":"Taking a balance back out to the bank it came from."},"app__api__v1__groups__TopUpRequest":{"properties":{"amount":{"type":"number","maximum":1000000.0,"exclusiveMinimum":0.0,"title":"Amount"}},"type":"object","required":["amount"],"title":"TopUpRequest"},"app__api__v1__guest__VerifyRequest":{"properties":{"razorpay_order_id":{"type":"string","maxLength":64,"minLength":4,"title":"Razorpay Order Id"},"razorpay_payment_id":{"type":"string","maxLength":64,"minLength":4,"title":"Razorpay Payment Id"},"razorpay_signature":{"type":"string","maxLength":256,"minLength":8,"title":"Razorpay Signature"}},"type":"object","required":["razorpay_order_id","razorpay_payment_id","razorpay_signature"],"title":"VerifyRequest"},"app__api__v1__referrals__ClaimRequest":{"properties":{"code":{"type":"string","maxLength":12,"minLength":4,"title":"Code"}},"type":"object","required":["code"],"title":"ClaimRequest"},"app__api__v1__vehicles__ClaimRequest":{"properties":{"registration":{"type":"string","maxLength":24,"minLength":4,"title":"Registration"},"kind":{"type":"string","title":"Kind","default":"shared"},"group_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Group Id"},"note":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Note"}},"type":"object","required":["registration"],"title":"ClaimRequest"},"app__api__v1__wallet__VerifyRequest":{"properties":{"razorpay_order_id":{"type":"string","maxLength":64,"minLength":4,"title":"Razorpay Order Id"},"razorpay_payment_id":{"type":"string","maxLength":64,"minLength":4,"title":"Razorpay Payment Id"},"razorpay_signature":{"type":"string","maxLength":256,"minLength":8,"title":"Razorpay Signature"}},"type":"object","required":["razorpay_order_id","razorpay_payment_id","razorpay_signature"],"title":"VerifyRequest","description":"What the provider's checkout sheet hands back to the app.\n\nEvery field is echoed straight through from the provider — none of it is\ntrusted until the signature over the first two verifies against our own\nsecret."},"app__schemas__charger__ChargerCreate":{"properties":{"ocpp_identity":{"type":"string","maxLength":64,"minLength":1,"title":"Ocpp Identity"},"name":{"type":"string","maxLength":120,"minLength":1,"title":"Name"},"station_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Station Id"}},"type":"object","required":["ocpp_identity","name"],"title":"ChargerCreate"},"app__schemas__wallet__TopUpRequest":{"properties":{"amount":{"type":"number","maximum":100000.0,"exclusiveMinimum":0.0,"title":"Amount"},"title":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Title"}},"type":"object","required":["amount"],"title":"TopUpRequest"},"app__schemas__website__ChargerCreate":{"properties":{"name":{"type":"string","maxLength":160,"minLength":1,"title":"Name"},"latitude":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Latitude"},"longitude":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Longitude"},"price_per_kwh":{"type":"number","minimum":0.0,"title":"Price Per Kwh"},"status":{"type":"string","maxLength":20,"title":"Status","default":"available"},"is_shared":{"type":"boolean","title":"Is Shared","default":false},"host_id":{"type":"integer","title":"Host Id"}},"type":"object","required":["name","latitude","longitude","price_per_kwh","host_id"],"title":"ChargerCreate"}}}}