API
API voor ontwikkelaars
Haal je laadpalen en laadsessies op in je eigen dashboard, script of koppeling. JSON over HTTPS, alleen lezen, met inloggen via OAuth.
Laatst bijgewerkt op
- Base-URL
- https://api.amfy.nl/api/v1
- Inloggen
- OAuth 2.1 met PKCE
- Formaat
- JSON, tijden in UTC, bedragen in centen
- Limiet
- 60 verzoeken per minuut
Inloggen met OAuth
Je app krijgt toegang via OAuth 2.1, met PKCE: de klant logt in bij Amfy en geeft je app toestemming. Je app krijgt dan een access-token, geen wachtwoord of sleutel. De meeste OAuth-bibliotheken doen de stappen hieronder zelf, met de gegevens uit https://api.amfy.nl/.well-known/oauth-authorization-server.
1. Je app registreren
Eén keer: je krijgt een client_id, een lange tekst die je bewaart zoals hij is. Als redirect_uri gebruik je een adres op je eigen computer (http://127.0.0.1 of http://localhost, de poort mag later anders zijn) of een https-adres van je eigen website. Een client secret is er niet: je app bewijst zich met PKCE.
curl https://api.amfy.nl/oauth/register \
-H "Content-Type: application/json" \
-d '{"client_name": "Mijn dashboard", "redirect_uris": ["http://127.0.0.1:8765/callback"]}'{
"client_id": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiTWlqbiBkYXNoYm9hcmQiLCJydXJpcyI6…",
"client_id_issued_at": 1792324206,
"client_name": "Mijn dashboard",
"redirect_uris": ["http://127.0.0.1:8765/callback"],
"token_endpoint_auth_method": "none",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"scope": "read"
}Heeft je app een https-adres met een Client ID Metadata Document, dan mag die URL ook direct de client_id zijn; registreren is dan niet nodig.
2. Inloggen in de browser
Maak een willekeurige code_verifier (43 tot 128 tekens) en de code_challenge daarbij: de SHA-256 ervan, in base64url zonder =. Open dan deze URL in de browser:
https://api.amfy.nl/oauth/authorize
?response_type=code
&client_id=JOUW_CLIENT_ID
&redirect_uri=http%3A%2F%2F127.0.0.1%3A8765%2Fcallback
&code_challenge=JOUW_CODE_CHALLENGE
&code_challenge_method=S256
&state=WILLEKEURIGE_TEKSTDe klant logt in en kiest Toegang geven. De browser gaat dan naar je redirect_uri, met een code die tien minuten geldig is:
http://127.0.0.1:8765/callback?code=CODE&iss=https%3A%2F%2Fapi.amfy.nl&state=WILLEKEURIGE_TEKSTControleer dat state klopt. Kiest de klant Annuleren, dan krijg je error=access_denied in plaats van een code. Klopt je verzoek zelf niet (bijvoorbeeld zonder PKCE), dan toont de pagina de fout en gaat de browser niet terug naar je app.
3. Tokens ophalen
curl https://api.amfy.nl/oauth/token \
-d grant_type=authorization_code \
-d code=CODE \
-d redirect_uri=http://127.0.0.1:8765/callback \
-d client_id=JOUW_CLIENT_ID \
-d code_verifier=JOUW_CODE_VERIFIER{
"access_token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9…",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "amfy_rt_…",
"scope": "read"
}Het access-token is een uur geldig. Daarna haal je een nieuw op met het refresh-token. Je krijgt dan ook een nieuw refresh-token: bewaar dat, want het oude werkt na een minuut niet meer. Gebruik je een oud refresh-token later toch nog eens, dan vervalt de koppeling en moet de klant opnieuw inloggen. Ververs niet vanuit twee processen tegelijk: dan blijft maar een van de twee nieuwe refresh-tokens werken.
curl https://api.amfy.nl/oauth/token \
-d grant_type=refresh_token \
-d refresh_token=amfy_rt_… \
-d client_id=JOUW_CLIENT_IDPer klant heeft je app één koppeling: logt de klant op een tweede apparaat in, dan werkt het refresh-token van het eerste niet meer. Een refresh-token dat 90 dagen niet is gebruikt, verloopt. Uitloggen in je app doe je met POST /oauth/revoke: stuur het refresh-token en je client_id mee (RFC 7009).
Je access-token gebruiken
Stuur het access-token bij elk verzoek mee in de header Authorization, met het woord Bearer en een spatie ervoor:
curl https://api.amfy.nl/api/v1/chargers \
-H "Authorization: Bearer JOUW_ACCESS_TOKEN"Antwoorden zijn JSON. Tijden zijn in UTC (bijvoorbeeld 2026-10-17T16:30:00Z), datums schrijf je als 2026-10-17, energie is in kWh en bedragen zijn in eurocenten.
Laadpalen ophalen
GET /api/v1/chargers geeft al je laadpalen, de oudste eerst. Eén laadpaal haal je op met GET /api/v1/chargers/{id}.
{
"chargers": [
{
"id": "3f6c2a1e-8b4d-4e2a-9c1f-5d7e8a9b0c12",
"name": "Laadpaal thuis",
"brand": "Zaptec",
"model": "Go 2",
"status": "active",
"startsOn": "2026-01-01",
"connectedAt": "2026-10-15T07:12:00Z",
"createdAt": "2026-10-14T18:00:00Z"
}
]
}| Veld | Betekenis |
|---|---|
id | Het kenmerk van de laadpaal, om laadsessies op te filteren |
name | De naam die je je laadpaal in de app gaf |
brand, model | Merk en model |
status | Hoe ver je aanmelding is (zie hieronder) |
startsOn | De ingangsdatum: vanaf deze dag tellen je laadsessies mee |
connectedAt | Wanneer je laadpaal gekoppeld is, of null |
createdAt | Wanneer je de laadpaal in de app toevoegde |
Status
| Status | Betekenis |
|---|---|
questions | De drie vragen over je laadpaal zijn nog niet beantwoord. |
rejected | Op basis van je antwoorden kan deze laadpaal (nog) niet meedoen. |
verification | De machtiging moet nog ondertekend worden met iDIN. |
review | Je laadpaal is aangemeld; wij controleren je gegevens. |
connection | Goedgekeurd: je kunt je laadpaal koppelen in de app. |
active | Gekoppeld. We halen je laadsessies op. |
Laadsessies ophalen
GET /api/v1/sessions geeft je laadsessies, de nieuwste eerst. Met deze parameters kies je welke:
| Parameter | Betekenis |
|---|---|
chargerId | Alleen de sessies van deze laadpaal |
from | Sessies die op of na dit moment begonnen: een datum (2026-09-01, middernacht Nederlandse tijd) of een tijdstip (2026-09-01T06:00:00Z) |
to | Sessies die vóór dit moment begonnen. Met from=2026-09-01&to=2026-10-01 krijg je precies september |
limit | Hoeveel sessies per keer: 1 tot 100, standaard 20 |
offset | Hoeveel sessies je overslaat, standaard 0. Met limit=20&offset=20 krijg je de tweede pagina |
curl "https://api.amfy.nl/api/v1/sessions?from=2026-09-01&to=2026-10-01&limit=1" \
-H "Authorization: Bearer JOUW_ACCESS_TOKEN"{
"sessions": [
{
"id": "9a1d5e0b-2c7f-4f43-8e6a-1b2c3d4e5f60",
"chargerId": "3f6c2a1e-8b4d-4e2a-9c1f-5d7e8a9b0c12",
"chargerName": "Laadpaal thuis",
"startedAt": "2026-09-29T16:30:00Z",
"endedAt": "2026-09-29T19:30:00Z",
"kwh": 16.375,
"amount": 206,
"final": false,
"meterStart": 1348.5,
"meterEnd": 1364.875
}
],
"limit": 1,
"offset": 0,
"totals": {
"count": 15,
"kwh": 245.625,
"amount": 3096,
"final": false
}
}| Veld | Betekenis |
|---|---|
id | Het kenmerk van de laadsessie |
chargerId, chargerName | De laadpaal van de sessie: het id en de name uit GET /api/v1/chargers |
startedAt, endedAt | Begin en eind van de laadsessie |
kwh | Hoeveel je hebt geladen, in kWh |
amount | Wat je voor deze sessie krijgt, in eurocenten (206 is € 2,06) |
final | false zolang het bedrag een schatting is met het indicatieve tarief; true als de ERE-prijs vaststaat |
meterStart, meterEnd | De stand van de MID-meter in je laadpaal bij begin en eind, in kWh, of null als je laadpaal die niet doorgeeft |
limit, offset | De pagina die je kreeg |
totals | Het aantal sessies (count), de kWh en het bedrag van álle sessies die bij je filters passen, niet alleen die op deze pagina. Handig voor een maandtotaal. final is false zolang een van die bedragen nog een schatting is |
Zolang offset plus limit kleiner is dan totals.count, zijn er meer sessies: vraag dezelfde lijst opnieuw op met een hogere offset (20, 40, …). Voor een totaal hoef je niet door te bladeren: dat staat al in totals. Laadsessies van vóór de ingangsdatum van je laadpaal tellen niet mee en staan er niet in.
Nieuwe laadsessies komen een paar keer per dag binnen, zodra wij ze bij de fabrikant van je laadpaal hebben opgehaald. Vaker dan eens per kwartier vragen heeft dus geen zin.
Fouten en limieten
Gaat er iets mis, dan krijg je een HTTP-status en een antwoord met een uitleg (error), een vaste code (code) en bij een ongeldige parameter de naam ervan (field):
{
"error": "to moet na from liggen.",
"code": "invalid_request",
"field": "to"
}| Status | Betekenis |
|---|---|
400 invalid_request | Een parameter klopt niet |
401 unauthorized | Geen access-token, of een dat verlopen of ingetrokken is. Haal een nieuw op met je refresh-token; lukt dat niet, laat de klant dan opnieuw inloggen |
404 not_found | Deze laadpaal bestaat niet, of is niet van jou |
429 rate_limited | Te veel verzoeken. De header Retry-After zegt na hoeveel seconden het weer kan |
500 internal | Er ging bij ons iets mis. Probeer het later opnieuw |
Fouten bij het inloggen (/oauth/token) volgen OAuth: error en error_description, bijvoorbeeld invalid_grant voor een verlopen code of refresh-token. Per account kun je ongeveer 60 verzoeken per minuut doen, de API en MCP samen.
Toegang intrekken
In de Amfy-app zie je onder Profiel → Gekoppelde apps welke apps toegang hebben, wanneer je ze koppelde en wanneer ze voor het laatst iets ophaalden. Kies Intrekken en de app kan meteen niet meer bij je gegevens; ook een token dat hij al had, werkt dan niet meer.
Wil je de app later weer gebruiken, koppel hem dan opnieuw vanuit de app zelf. Een app die 90 dagen niets bij ons ophaalt, moet je ook opnieuw koppelen.
Veiligheid en privacy
- Een gekoppelde app leest alleen je laadpalen en laadsessies. Je profiel, je rekeningnummer en je uitbetalingen zitten er niet in, en veranderen kan niet.
- Je logt altijd in bij Amfy zelf, op
api.amfy.nl. De app die je koppelt, ziet je e-mailadres en je code niet. - Voordat je toegang geeft, zie je welke app het is en waar je daarna naartoe gaat. Herken je de app niet, kies dan Annuleren.
- Wij bewaren de tokens van een app niet zelf, alleen een onleesbare afgeleide (hash). Trek je de toegang in, dan werken ze meteen nergens meer.
- Wat een andere app of assistent met je gegevens doet, valt onder het privacybeleid van die app. Hoe wij met je gegevens omgaan, lees je in de privacyverklaring.
Vragen over de API? Mail ons via [email protected].