API Keys & Integration
Connect your website or app to NavYour delivery APIs. Create test orders, verify your connection, and go live safely.
Test API Key
Use the Test API key while integrating your website. Test orders appear in this page and do not create real deliveries.
Never place this key in frontend JavaScript, HTML, mobile app public code, or GitHub. Store it only in your backend/server .env.
Create a test key and copy it once. Stored keys are shown only as prefix and last four characters.
Live API Key
Live API creates real NavYour delivery orders and may deduct delivery fees from your wallet.
Live orders deduct deliveryFeePaise from your NavYour wallet. Create a live key only after a successful test order.
Live API may be locked until profile, subscription, wallet, and live access requirements are ready.
Test Orders / Connection Test
Send a test order from your website/backend using your Test API key. If the integration is correct, the test order will appear below within a few seconds.
How to connect your website to NavYour
Click Create Test API Key. Copy it once and save it in your backend .env.
NAVYOUR_API_BASE_URL=https://api.navyour.com/v1 NAVYOUR_API_KEY=nvy_test_xxxxxxxxxxxxx # Local NavYour testing NAVYOUR_API_BASE_URL=http://localhost:3000/v1 NAVYOUR_API_KEY=nvy_test_xxxxxxxxxxxxx
Add backend code after checkout/order confirmation. Do not call NavYour from frontend.
Send customer, pickup, delivery, package, payment, deliveryFeePaise, codAmountPaise, and orderReference to POST /integration/orders.
{
"orderReference": "STORE-ORDER-1001",
"orderSource": "business_website",
"customer": {
"name": "Rahul Sharma",
"phone": "+919876543210",
"email": "rahul@example.com"
},
"delivery": {
"addressLine1": "Paona Bazaar",
"addressLine2": "Near Ima Market",
"city": "Imphal",
"state": "Manipur",
"pincode": "795001",
"landmark": "Near main gate",
"latitude": 24.8072,
"longitude": 93.9368,
"fullAddress": "Paona Bazaar, near Ima Market, Imphal, Manipur 795001"
},
"pickup": {
"businessName": "Fresh Store",
"contactName": "Nashei H",
"phone": "+919876543210",
"addressLine1": "MG Avenue",
"city": "Imphal",
"state": "Manipur",
"pincode": "795001",
"fullAddress": "MG Avenue, Shop No. 12, Imphal, Manipur 795001"
},
"package": {
"description": "Customer grocery order",
"items": [{ "name": "Rice bag", "quantity": 1, "pricePaise": 80000 }],
"totalItems": 1,
"weightKg": 5,
"fragile": false
},
"payment": {
"paymentType": "cod",
"orderValuePaise": 130000,
"deliveryFeePaise": 4000,
"codAmountPaise": 134000,
"prepaidAmountPaise": 0,
"currency": "INR"
}
}After your backend sends a test order, refresh this page. If the test order appears in Test Orders, connection is correct.
After order creation, NavYour can send status updates back to your website through webhooks.
Create Live API key only after test order received successfully, profile is complete, subscription is active, wallet is funded, and webhooks are configured if needed.
Your website decides the delivery fee and sends deliveryFeePaise to NavYour. NavYour validates this amount and deducts the same delivery fee from your NavYour wallet for live orders.
Customer pays your business. Your NavYour wallet pays NavYour delivery fee.
codAmountPaise is the exact cash amount the driver must collect from the customer. If your checkout total includes delivery fee, include delivery fee inside codAmountPaise.
Test orders do not deduct wallet balance and do not assign drivers.
async function createNavYourDelivery(savedOrder) {
if (savedOrder.navyourTrackingCode) {
return {
alreadyCreated: true,
trackingCode: savedOrder.navyourTrackingCode,
trackingUrl: savedOrder.navyourTrackingUrl,
};
}
const payload = {
orderReference: String(savedOrder.id),
orderSource: "business_website",
customer: {
name: savedOrder.customerName,
phone: savedOrder.customerPhone,
email: savedOrder.customerEmail || null,
},
delivery: {
addressLine1: savedOrder.shippingAddressLine1,
addressLine2: savedOrder.shippingAddressLine2 || null,
city: savedOrder.shippingCity,
state: savedOrder.shippingState,
pincode: savedOrder.shippingPincode,
landmark: savedOrder.shippingLandmark || null,
latitude: savedOrder.deliveryLatitude || null,
longitude: savedOrder.deliveryLongitude || null,
fullAddress: savedOrder.shippingFullAddress,
},
pickup: {
businessName: process.env.STORE_NAME,
contactName: process.env.STORE_CONTACT_NAME,
phone: process.env.STORE_PHONE,
addressLine1: process.env.STORE_ADDRESS_LINE1,
addressLine2: process.env.STORE_ADDRESS_LINE2 || null,
city: process.env.STORE_CITY,
state: process.env.STORE_STATE,
pincode: process.env.STORE_PINCODE,
landmark: process.env.STORE_LANDMARK || null,
latitude: process.env.STORE_LATITUDE ? Number(process.env.STORE_LATITUDE) : null,
longitude: process.env.STORE_LONGITUDE ? Number(process.env.STORE_LONGITUDE) : null,
fullAddress: process.env.STORE_FULL_ADDRESS,
},
package: {
description: savedOrder.packageDescription || "Customer order package",
items: savedOrder.items.map((item) => ({
name: item.name,
quantity: item.quantity,
pricePaise: item.pricePaise,
})),
totalItems: savedOrder.items.length,
weightKg: savedOrder.weightKg || null,
fragile: Boolean(savedOrder.fragile),
specialInstructions: savedOrder.deliveryInstructions || null,
},
payment: {
paymentType: savedOrder.paymentMode === "COD" ? "cod" : "prepaid",
orderValuePaise: savedOrder.orderValuePaise,
deliveryFeePaise: savedOrder.deliveryFeePaise,
codAmountPaise: savedOrder.paymentMode === "COD" ? savedOrder.codAmountPaise : 0,
prepaidAmountPaise: savedOrder.paymentMode === "COD" ? 0 : savedOrder.paidAmountPaise,
currency: "INR",
},
notes: {
customerNote: savedOrder.customerNote || null,
internalNote: savedOrder.internalNote || null,
},
};
const response = await fetch(`${process.env.NAVYOUR_API_BASE_URL}/integration/orders`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${process.env.NAVYOUR_API_KEY}`,
"Idempotency-Key": String(savedOrder.id),
},
body: JSON.stringify(payload),
});
const data = await response.json().catch(() => null);
if (!response.ok) {
await markNavYourSyncFailed(savedOrder.id, data?.message || "NavYour delivery creation failed");
throw new Error(data?.message || "NavYour delivery creation failed");
}
await saveNavYourTracking(savedOrder.id, {
navyourOrderId: data.id,
navyourTrackingCode: data.trackingCode,
navyourTrackingUrl: data.trackingUrl,
navyourDeliveryStatus: data.status,
navyourSyncStatus: "created",
});
return data;
}401 Invalid API key: check the backend env value and never use frontend code.
403 Live API locked: complete profile, activate subscription, fund wallet, or continue using test key.
400 Missing deliveryFeePaise: send the delivery fee amount in paise.
400 Missing customer/delivery details: send full customer and delivery address.
402 Wallet balance low: top up wallet before live orders.
409 Duplicate orderReference: use the existing tracking code or retry safely with the same Idempotency-Key.
Prompt for your developer/Codex
You are working in this website backend. Integrate NavYour delivery creation after our checkout/order-confirmation flow.
Goal:
When a customer order is confirmed in our system, create one NavYour delivery order from the backend, store the returned tracking details on our order, and make retries safe. First use the NavYour Test API key. Do not switch to Live until a test order appears in NavYour Business Portal -> API Keys -> Test Orders.
NavYour API:
- Base URL env: NAVYOUR_API_BASE_URL
- API key env: NAVYOUR_API_KEY
- Endpoint: POST {NAVYOUR_API_BASE_URL}/integration/orders
- Auth header: Authorization: Bearer {NAVYOUR_API_KEY}
- Idempotency header: Idempotency-Key: use our order id or immutable order reference
- Content-Type: application/json
Security rules:
- Store NAVYOUR_API_KEY only in backend/server environment variables.
- Never expose the key in frontend JavaScript, HTML, mobile app code, logs, analytics, error trackers, GitHub, or API responses.
- Do not call NavYour from the browser. Only our backend may call NavYour.
- Redact Authorization and NAVYOUR_API_KEY from logs.
Database changes/checks:
- Add or reuse fields on our orders table:
navyourOrderId
navyourTrackingCode
navyourTrackingUrl
navyourDeliveryStatus
navyourSyncStatus: not_started | creating | created | failed
navyourSyncError
navyourLastSyncAttemptAt
- Add a unique guard so the same local order cannot create multiple NavYour deliveries.
- Store the NavYour response payload or minimal audit metadata if this project has an integration-log table.
When to call NavYour:
- Call only after our local order is successfully saved/confirmed.
- Never create a NavYour delivery before payment/order confirmation.
- If the customer order is COD, send paymentType "cod".
- If the customer paid online, send paymentType "prepaid".
Payload requirements:
- Send a complete JSON payload with:
orderReference: our stable order id/reference
orderSource: "business_website"
customer.name, customer.phone, customer.email
delivery full address and address fields
pickup store/business address and contact fields
package description/items/totalItems/weightKg/fragile/specialInstructions
payment.paymentType
payment.orderValuePaise
payment.deliveryFeePaise
payment.codAmountPaise
payment.prepaidAmountPaise
payment.currency: "INR"
notes.customerNote and notes.internalNote when available
Money rules:
- deliveryFeePaise is required and must be greater than 0.
- Our website decides deliveryFeePaise and sends it to NavYour.
- In Live mode, NavYour deducts this deliveryFeePaise from our NavYour wallet.
- Customer payment belongs to our business. NavYour wallet pays the NavYour delivery fee.
- For COD, codAmountPaise must be the exact cash amount the driver collects from the customer.
- If our checkout total includes delivery fee, include that delivery fee inside codAmountPaise.
- For prepaid orders, prepaidAmountPaise is the amount already collected by our website.
Idempotency and duplicate prevention:
- Before calling NavYour, check if the order already has navyourTrackingCode. If yes, return the existing tracking details.
- Send Idempotency-Key with the same stable local order id on every retry.
- Use the same orderReference on every retry.
- Treat 409 duplicate/order already exists as recoverable if NavYour returns or can recover a tracking code.
Failure behavior:
- If NavYour fails, do not delete or cancel the customer order.
- Save navyourSyncStatus = "failed", save the error message, and allow admin/background retry.
- Retry only from backend using the same orderReference and Idempotency-Key.
- Surface a clear internal error for operations, but do not expose API keys or raw sensitive headers.
Expected success response handling:
- Parse JSON response.
- Save:
data.id or data.navyourOrderId -> navyourOrderId
data.trackingCode -> navyourTrackingCode
data.trackingUrl -> navyourTrackingUrl
data.status -> navyourDeliveryStatus
navyourSyncStatus = "created"
Webhook receiver:
- Create POST /api/navyour/webhook in this website backend.
- Store NAVYOUR_WEBHOOK_SECRET only in backend .env.
- Verify NavYour-Signature with raw body before parsing JSON.
- Signature payload is NavYour-Timestamp + "." + rawBody.
- Update our local order using event.order.orderReference or event.order.trackingCode.
- Return HTTP 200 quickly. Do heavy work after response if needed.
- Handle at least driver.assigned, order.picked_up, order.out_for_delivery, order.delivered, order.failed, order.cancelled, cod.collected, cod.handed_over, and cod.settled.
- Never create customer orders from webhook payloads. Webhook only updates delivery status after API order creation.
Testing steps:
1. Put the NavYour Test API key in backend .env as NAVYOUR_API_KEY.
2. Keep NAVYOUR_API_BASE_URL pointed to the NavYour API base URL.
3. Place a real test checkout/order through our website flow.
4. Confirm our backend sends POST /integration/orders with Authorization Bearer and Idempotency-Key.
5. Confirm the order appears in NavYour Business Portal -> API Keys -> Test Orders.
6. Confirm NavYour returns a TEST tracking code.
7. Confirm our order stores trackingCode and trackingUrl.
8. Confirm duplicate retry does not create a second NavYour delivery.
9. Confirm failed NavYour calls mark sync failed and can be retried.
10. Configure NavYour webhook URL and signing secret.
11. Send test webhook and verify signature handling.
12. Confirm webhook events update local order delivery status.
Go-live checklist:
- A test order appears successfully in NavYour Business Portal.
- The local order stores NavYour tracking details.
- Duplicate retry has been tested.
- Failure/retry behavior has been tested.
- Webhook endpoint is configured and test webhook succeeded.
- Business profile, subscription, and wallet are ready in NavYour.
- Only then replace the Test API key with the Live API key in backend .env.
Implement this using the existing backend framework, existing order model/service patterns, existing logger, and existing environment config style in this repository. Add focused tests for payload construction, idempotency guard, success persistence, and failure persistence.Webhook Next Step
Configure WebhookAfter test order appears, configure webhook to receive delivery updates automatically.
