Quickstart
Deze quickstart draait volledig in de sandbox op https://api.eftisandbox.app. Er wordt niets
vervoerd en niets gefactureerd; sandbox-data staat los van live-data.
-
Haal een API-key op
Section titled “Haal een API-key op”Elke call gaat met
Authorization: Bearer <key>. De prefix bepaalt de modus:sk_test_praat met de sandbox,sk_live_met productie.Zet de key in je omgeving zodat hij niet in je shell-geschiedenis of je repo belandt:
Terminal window export FREIGHTAPI_KEY="sk_test_..."export FREIGHTAPI_BASE_URL="https://api.eftisandbox.app"Controleer of de key werkt:
Terminal window curl -s "$FREIGHTAPI_BASE_URL/v1/shipments?limit=1" \-H "Authorization: Bearer $FREIGHTAPI_KEY"Een
401met codeinvalid_api_keybetekent dat de key niet bestaat of is ingetrokken; zie Foutcodes. -
Maak je eerste zending
Section titled “Maak je eerste zending”Een zending heeft minimaal een afzender, een vervoerder, een geadresseerde, een laadadres, een losadres en goederen. Alles daarbuiten is optioneel en vult de eFTI-dataset verder aan.
Terminal window curl -s -X POST "$FREIGHTAPI_BASE_URL/v1/shipments" \-H "Authorization: Bearer $FREIGHTAPI_KEY" \-H "Content-Type: application/json" \-d '{"reference": "ORD-1042","transport_type": "international","consignor": {"name": "Demo Logistics B.V.","address": { "street": "Havenweg 12", "postal_code": "3089 JG", "city": "Rotterdam", "country": "NL" }},"carrier": {"name": "Transport Nowak Sp. z o.o.","address": { "street": "ul. Przemyslowa 8", "postal_code": "61-001", "city": "Poznan", "country": "PL" }},"consignee": {"name": "Mueller Maschinenbau GmbH","address": { "street": "Industriestrasse 4", "postal_code": "70565", "city": "Stuttgart", "country": "DE" }},"pickup": { "address": { "street": "Havenweg 12", "postal_code": "3089 JG", "city": "Rotterdam", "country": "NL" } },"delivery": { "address": { "street": "Industriestrasse 4", "postal_code": "70565", "city": "Stuttgart", "country": "DE" } },"goods": [{ "description": "CNC machine parts", "quantity": 12, "package_type": "pallet", "gross_weight_kg": 8400 }]}'import { FreightApi } from '@freightapi/sdk'const freight = new FreightApi({apiKey: process.env.FREIGHTAPI_KEY!,baseUrl: 'https://api.eftisandbox.app',})const shipment = await freight.shipments.create({reference: 'ORD-1042',transport_type: 'international',consignor: {name: 'Demo Logistics B.V.',address: { street: 'Havenweg 12', postal_code: '3089 JG', city: 'Rotterdam', country: 'NL' },},carrier: {name: 'Transport Nowak Sp. z o.o.',address: { street: 'ul. Przemyslowa 8', postal_code: '61-001', city: 'Poznan', country: 'PL' },},consignee: {name: 'Müller Maschinenbau GmbH',address: { street: 'Industriestraße 4', postal_code: '70565', city: 'Stuttgart', country: 'DE' },},pickup: { address: { street: 'Havenweg 12', postal_code: '3089 JG', city: 'Rotterdam', country: 'NL' } },delivery: { address: { street: 'Industriestraße 4', postal_code: '70565', city: 'Stuttgart', country: 'DE' } },goods: [{ description: 'CNC machine parts', quantity: 12, package_type: 'pallet', gross_weight_kg: 8400 },],})console.log(shipment.id, shipment.status)// De officiële .NET-SDK komt met M3-17. Tot die tijd is Cargofollow een gewone REST-API:// gebruik HttpClient en System.Text.Json.using var http = new HttpClient { BaseAddress = new Uri("https://api.eftisandbox.app") };http.DefaultRequestHeaders.Authorization =new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("FREIGHTAPI_KEY"));var response = await http.PostAsJsonAsync("/v1/shipments", shipmentCreate);response.EnsureSuccessStatusCode();var shipment = await response.Content.ReadFromJsonAsync<Shipment>();Je krijgt
201 Createdterug met de volledige zending:{"id": "shp_01M2FP3DE7YQ1Z24SBT4317SM2","mode": "test","status": "draft","version": 1,"current_version": {"id": "ver_01M2FP3DE7HZH0ENF0VH2CKXVB","version": 1,"document_hash": "54db818c1f898ad691916212ecba15582f56a9c4e3edef4850c5e62abc24da57"},"warnings": [{"path": "consignee.contact","code": "consignee_contact_for_delivery_signature","message": "Without an email address or phone number for the consignee no signature can be requested on delivery."}]}Bewaar de
id:Terminal window export SHIPMENT_ID="shp_01M2FP3DE7YQ1Z24SBT4317SM2" -
Geef de vrachtbrief uit
Section titled “Geef de vrachtbrief uit”Zolang een zending
draftis, verandert ze vrij. Uitgeven bevriest de vrachtbriefvelden en zet de eerste schakel in de hash-keten.Terminal window curl -s -X POST "$FREIGHTAPI_BASE_URL/v1/shipments/$SHIPMENT_ID/issue" \-H "Authorization: Bearer $FREIGHTAPI_KEY" \-H "Content-Type: application/json" \-d '{}'const issued = await freight.shipments.issue(shipment.id)console.log(issued.status, issued.current_version.document_hash)var issued = await http.PostAsJsonAsync($"/v1/shipments/{shipmentId}/issue", new { });issued.EnsureSuccessStatusCode();De status staat nu op
issuedenissued_atis gevuld. EenPATCHop een bevroren veld geeft vanaf nufield_frozen. -
Open de tekenlink
Section titled “Open de tekenlink”Een uitgegeven zending heeft een inspectielink: een token-URL met QR-code die een chauffeur, ontvanger of handhaver zonder account kan openen.
Terminal window curl -s "$FREIGHTAPI_BASE_URL/v1/shipments/$SHIPMENT_ID/inspection-link" \-H "Authorization: Bearer $FREIGHTAPI_KEY"{"token_id": "ins_01M2FP54YDY3DTNK4GQE1JPT8K","url": "https://sign.eftisandbox.app/i/CvtAOsHboY80GbORQNUOztOW3INHRSHGFd8kQ4FN4Dc","expires_at": "2027-09-14T10:07:12.845Z","qr_svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" ...>"}Open
urlin je browser, of printqr_svgop de vrachtbrief. De PNG- en SVG-varianten van de QR-code staan los op/v1/inspection-links/{token_id}/qr.pngen.../qr.svg. Lekt een link, dan trek je hem in metPOST /v1/shipments/{id}/inspection-link/rotate; de oude token geeft daarnatoken_rotated. -
Ontvang een webhook
Section titled “Ontvang een webhook”In plaats van te pollen abonneer je een endpoint op gebeurtenissen.
Terminal window curl -s -X POST "$FREIGHTAPI_BASE_URL/v1/webhook-endpoints" \-H "Authorization: Bearer $FREIGHTAPI_KEY" \-H "Content-Type: application/json" \-d '{"url": "https://example.com/hooks/freightapi","events": ["shipment.issued", "shipment.delivered"],"description": "Quickstart"}'{"id": "whe_01M2FP5AJCSSDQYQVAV865N8Q0","url": "https://example.com/hooks/freightapi","events": ["shipment.issued", "shipment.delivered"],"active": true,"mode": "test","secret": "whsec_0HBh8opWaFo6YUdG96sf8gPpk2ydhA4oxjVHuLGASSN"}Stuur jezelf een testping en verifieer de handtekening:
Terminal window curl -s -X POST "$FREIGHTAPI_BASE_URL/v1/webhook-endpoints/$ENDPOINT_ID/test" \-H "Authorization: Bearer $FREIGHTAPI_KEY"In je handler verifieer je de
freightapi-signature-header vóórdat je de body vertrouwt:import { parseEvent } from '@freightapi/sdk/webhooks'const event = await parseEvent({secret: process.env.FREIGHTAPI_WEBHOOK_SECRET!,header: request.headers,// De body exact zoals hij binnenkwam; nooit de geparste JSON opnieuw serialiseren.body: await request.text(),})console.log(event.type, event.data)Wat er bij een mislukte aflevering gebeurt — retries, de dead-letter queue en het opnieuw afspelen van een levering — staat onder Webhooks.
-
Laat de sandbox de rit rijden
Section titled “Laat de sandbox de rit rijden”In de sandbox hoef je niet zelf een chauffeur te spelen.
simulatemetaction: "auto"loopt de hele levenscyclus af: ondertekenen door afzender en vervoerder, onderweg, afleveren met de handtekening van de geadresseerde.Terminal window curl -s -X POST "$FREIGHTAPI_BASE_URL/v1/test/shipments/$SHIPMENT_ID/simulate" \-H "Authorization: Bearer $FREIGHTAPI_KEY" \-H "Content-Type: application/json" \-d '{"action": "auto"}'Volg daarna wat er gebeurd is:
Terminal window curl -s "$FREIGHTAPI_BASE_URL/v1/shipments/$SHIPMENT_ID/events" \-H "Authorization: Bearer $FREIGHTAPI_KEY"Elke gebeurtenis draagt een
seq, eenhashen deprev_hashvan zijn voorganger. Of die keten klopt, controleer je metGET /v1/shipments/{id}/integrity.
Hierna
Section titled “Hierna”- API-reference — alle routes, direct uit te proberen tegen de sandbox.
- Foutcodes — elke stabiele
codedie de API teruggeeft. - SDK’s — de TypeScript-client en wat er nog aankomt.