This page documents the two Neptune endpoints used by the uDrew integration.
It is intended as a technical reference for implementation and troubleshooting.
Overview
Neptune currently exposes two separate uDrew endpoints:
udrewIntakereceives uDrew lead submissions and upserts them into Neptune.uDrewWidgetreceives generated planning images and saves them into a Neptune customer record.
These endpoints do different jobs and use different authentication rules.
| Endpoint | Purpose | Auth |
|---|---|---|
udrewIntake | Create or update a uDrew lead in Neptune | x-api-key required |
uDrewWidget | Save a generated image to a Neptune customer upload record | No API key required |
Environment URLs
Production
https://us-central1-netpune-220210.cloudfunctions.net/udrewIntakehttps://us-central1-netpune-220210.cloudfunctions.net/uDrewWidget
Staging
https://us-central1-neptune-dev-753ab.cloudfunctions.net/udrewIntakehttps://us-central1-neptune-dev-753ab.cloudfunctions.net/uDrewWidget
1. udrewIntake
Use this endpoint for inbound lead submissions from the uDrew website lead generator.
Request
- Method:
POST - Headers:
Content-Type: application/jsonx-api-key: <your-uDrew-api-key>
Authentication
The API key must be an active Neptune organisation API key for the uDrew integration.
You can generate this in Neptune under Admin → Integrations → uDrew.
Request body
All body fields are optional in the current implementation. However, for a useful lead record you should normally send at least one identifying field such as name, email, phone, address, or sessionId.
| Field | Type | Required | Notes |
|---|---|---|---|
address | string | No | Postal or site address for the lead |
firstName | string | No | Lead first name |
lastName | string | No | Lead last name |
email | string | No | Lead email address |
phone | string | No | Lead phone number |
message | string | No | Free-text enquiry message |
sessionId | string | No | If provided, Neptune uses this to find and update an existing uDrew lead instead of creating a new one |
latitude | number | string | No | Latitude value. Neptune accepts either a number or a numeric string |
longitude | number | string | No | Longitude value. Neptune accepts either a number or a numeric string |
featureId | string | No | Optional uDrew feature identifier |
featureID | string | No | Alternative accepted key for featureId |
featureName | string | No | Optional uDrew feature name |
featureType | string | No | Optional uDrew feature type |
imageData | string | No | Base64 image string, with or without a data:image/...;base64, prefix |
Example body
{
"address": "12 Example Street, Bristol",
"firstName": "Jamie",
"lastName": "Taylor",
"email": "jamie@example.com",
"phone": "07700111222",
"message": "Interested in a pool design",
"sessionId": "udrew-session-12345",
"latitude": 51.4545,
"longitude": -2.5879,
"featureId": "feature_456",
"featureName": "Rectangle Pool",
"featureType": "pool",
"imageData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}
Example request
curl -X POST "https://us-central1-netpune-220210.cloudfunctions.net/udrewIntake" \
-H "Content-Type: application/json" \
-H "x-api-key: <your-uDrew-api-key>" \
-d '{
"address": "12 Example Street, Bristol",
"firstName": "Jamie",
"lastName": "Taylor",
"email": "jamie@example.com",
"phone": "07700111222",
"message": "Interested in a pool design",
"sessionId": "udrew-session-12345",
"latitude": 51.4545,
"longitude": -2.5879,
"featureId": "feature_456",
"featureName": "Rectangle Pool",
"featureType": "pool",
"imageData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}'
What Neptune does
- Validates the
x-api-key. - Looks for an existing
udrewLeadsrecord with the samesessionIdif one is provided. - Updates that record if found, or creates a new one if not found.
- Saves feature metadata if
featureId,featureID,featureName, orfeatureTypeare provided. - Converts
latitudeandlongitudeinto a NeptunelatLngvalue when both coordinates are present and valid numbers. - Uploads
imageDatato storage if it is present. - Returns the Neptune lead record ID.
If image upload fails, Neptune still continues processing the lead submission and returns success if the lead itself was saved.
If the organisation has Neptune sequencing enabled, Neptune may also create a Lead record automatically from the uDrew submission.
Field handling notes
- Neptune accepts either
featureIdorfeatureID. If both are present,featureIdis used. - Neptune only saves location data when both
latitudeandlongitudeare provided and can be parsed into valid numbers. - When sequencing is enabled, the saved
latLngvalue is also copied onto the auto-created Lead record.
Success response
{
"ok": true,
"leadId": "abc123",
"isUpdate": false
}
| Field | Type | Notes |
|---|---|---|
ok | boolean | true when the request succeeded |
leadId | string | Neptune ID of the udrewLeads record |
isUpdate | boolean | true when an existing record was matched by sessionId and updated |
Error responses
| Status | Error | When it happens |
|---|---|---|
401 | invalid_api_key | API key is missing, revoked, invalid, or not for the uDrew integration |
405 | method_not_allowed | Request method is not POST |
500 | internal_error | Unexpected server-side failure |
2. uDrewWidget
Use this endpoint when the uDrew planning widget built into Neptune sends a generated image back to Neptune for a specific customer.
Request
- Method:
POST - Headers:
Content-Type: application/json
Authentication
This endpoint does not use an API key.
Instead, Neptune validates the provided customerId by checking that the customer exists and has an organisationId.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
customerId | string | Yes | Neptune customer ID that should receive the uploaded image |
featureId | string | Yes | uDrew feature identifier |
imageData | string | Yes | Base64 image string, with or without a data:image/...;base64, prefix |
featureName | string | No | Used as the upload label and filename when present |
featureType | string | No | Used if featureName is not provided |
Example body
{
"customerId": "customer_123",
"featureId": "feature_456",
"featureName": "Rectangle Pool",
"featureType": "pool",
"imageData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}
Example request
curl -X POST "https://us-central1-netpune-220210.cloudfunctions.net/uDrewWidget" \
-H "Content-Type: application/json" \
-d '{
"customerId": "customer_123",
"featureId": "feature_456",
"featureName": "Rectangle Pool",
"featureType": "pool",
"imageData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}'
What Neptune does
- Confirms
customerId,featureId, andimageDataare present. - Loads the Neptune customer record.
- Uses the customer’s
organisationIdto determine where to store the image. - Uploads the image to storage.
- Creates a new record in
customers/{customerId}/uploads.
The saved upload uses:
featureNameas the label if present- otherwise
featureType - otherwise
uDrew Generated
Success response
{
"ok": true,
"imageBucket": "org123/customerUploads/customer_123/udrew-1710000000000_Rectangle-Pool.png",
"customerId": "customer_123",
"featureId": "feature_456"
}
| Field | Type | Notes |
|---|---|---|
ok | boolean | true when the request succeeded |
imageBucket | string | Storage path of the uploaded image |
customerId | string | Echoes the target Neptune customer ID |
featureId | string | undefined | Echoes the provided feature ID when present |
Error responses
| Status | Error | When it happens |
|---|---|---|
400 | missing_required_fields | customerId, featureId, or imageData is missing |
404 | customer_not_found | customerId does not match a Neptune customer |
405 | method_not_allowed | Request method is not POST |
500 | missing_organisation_id | Customer exists but is missing an organisation association |
500 | internal_error | Unexpected server-side failure |
Image format notes
Both endpoints accept imageData as either:
- a full data URL, for example
data:image/png;base64,... - a raw base64 string
Neptune currently recognises:
image/jpegimage/jpgimage/webp
If the image type cannot be recognised from the provided string, Neptune defaults to png.