Skip to main content
For platform users: See the Data Input overview to understand how connections and data processing work.

Overview

Webhooks are POST requests sent to your endpoint when events occur in Nectar — connections created, documents processed, and more. Your endpoint should return a 2xx response within 15 seconds to acknowledge receipt. If your framework enables CSRF protection by default, disable it for the webhook endpoint. Verify every incoming webhook using signature verification before processing.

Set up webhooks

1

Get your webhook portal URL

Call the configure webhook endpoint (see the API Reference tab) with your API key. The response contains a Svix portal URL valid for 7 days.
2

Add an endpoint

In the Svix portal, add your endpoint URL and select the event types you want to subscribe to. If you don’t select any event types, the endpoint receives all events by default.
If you don’t have a URL ready yet, click Use Svix Play to generate a temporary URL where you can inspect incoming events.
3

Test your endpoint

Use the Testing tab in the Svix portal to send example events to your endpoint. Click into any message to view the payload, delivery attempts, and success or failure status.

Event types

Nectar sends the following event types. Each event fires only when there is a meaningful data change — timestamp-only updates are ignored.
Event typeTriggerCommon scenarios
connection.created.v2A new connection is created via the API or magic link.User submits credentials for a new utility provider.
connection.updated.v2Any field on the connection changes (status, accounts, site assignments, credentials, or other details).Status transitions (e.g., PENDINGCONNECTED), credential updates, account tracking changes, site reassignments.
connection.validated.v2A connection’s status changes — Nectar has verified the credentials or detected a status transition.Initial validation after creation, weekly check finds a credential error, or a previously errored connection recovers.
document.created.v2A new document (utility bill) is processed and available.Nectar scrapes a new bill from the utility provider, or a bill is uploaded via document upload.
document.updated.v2An existing document is reprocessed and its data changes.A bill is corrected, meter assignments change, or usage data is updated via the API.
document.deleted.v2A document is deleted. The payload contains the document state at the time of deletion.A bill is removed via the API or through the platform.
connection.updated.v2 vs connection.validated.v2: A single connection change can fire both events. connection.validated.v2 fires whenever the connection’s status changes. connection.updated.v2 fires whenever any connection field changes (which may or may not include a status change). If a status change also modifies other fields, you receive both events.
Browse the full list in the Svix event catalog.

connection.created.v2

Sent when a new connection is created via the API, magic link, or the platform. Fires once per connection at creation time.
{
  "company": {
    "externalId": "269350a4-8595-42cc-96ee-bf047d093505",
    "id": "91c21c6b-5f3f-4d5f-9fb9-02530ef4b13c",
    "name": "Demo Company",
    "publicId": "cb78b85c-e68e-48de-a99e-e88862076823"
  },
  "created": "2024-09-06T00:15:43.073014",
  "datasource": {
    "name": "Los Angeles Department of Water and Power"
  },
  "id": "a6c70a54-34e7-4277-80b0-412869ce087c",
  "sitesRelations": [
    {
      "accountIds": ["0137746423"],
      "datasourceTypes": ["ELECTRICITY"],
      "site": {
        "id": "67e72ddf-9e9c-42b6-81da-13c1130c691a",
        "name": "California Facility 1"
      }
    }
  ],
  "status": "CONNECTED",
  "updated": "2024-09-06T00:15:43.073032",
  "url": "https://ladwp.com"
}

connection.updated.v2

Sent when any field on a connection changes. This includes status transitions, credential updates, account additions or removals, site reassignments, and any other connection detail change. The event fires only when the serialized connection differs from its previous state — timestamp-only updates do not trigger this event. The payload includes protectedChanges (a list of sensitive fields that changed, such as username, password, or securityQuestions) and old (previous values so you can see what changed).
{
  "eventType": "connection.updated.v2",
  "protectedChanges": ["status"],
  "old": {
    "status": "PENDING"
  },
  "company": {
    "externalId": "269350a4-8595-42cc-96ee-bf047d093505",
    "id": "91c21c6b-5f3f-4d5f-9fb9-02530ef4b13c",
    "name": "Demo Company",
    "publicId": "cb78b85c-e68e-48de-a99e-e88862076823"
  },
  "created": "2024-09-06T00:15:43.073014",
  "datasource": {
    "name": "Los Angeles Department of Water and Power"
  },
  "id": "a6c70a54-34e7-4277-80b0-412869ce087c",
  "sitesRelations": [
    {
      "accountIds": ["0137746423"],
      "datasourceTypes": ["ELECTRICITY"],
      "site": {
        "id": "67e72ddf-9e9c-42b6-81da-13c1130c691a",
        "name": "California Facility 1"
      }
    }
  ],
  "status": "CONNECTED",
  "updated": "2024-09-07T12:30:00.000000",
  "url": "https://ladwp.com"
}

connection.validated.v2

Sent when a connection’s status changes. This fires on any status transition — not only the initial validation after creation, but also when a connected account encounters a credential error, when a provider goes down, or when an errored connection recovers. If a connection’s status changes, you always receive this event. The payload shape is the same as connection.updated.v2.
Use connection.validated.v2 to track status transitions specifically, and connection.updated.v2 to track all connection changes including non-status fields.

document.created.v2

Sent when a new document (utility bill) is processed and available. This fires when Nectar scrapes a new bill from a utility provider or when a bill is uploaded via the document upload flow.
{
  "eventType": "document.created.v2",
  "id": "b2d4e6f8-1234-5678-9abc-def012345678",
  "company": {
    "externalId": "269350a4-8595-42cc-96ee-bf047d093505",
    "id": "91c21c6b-5f3f-4d5f-9fb9-02530ef4b13c",
    "name": "Demo Company",
    "publicId": "cb78b85c-e68e-48de-a99e-e88862076823"
  },
  "site": {
    "id": "67e72ddf-9e9c-42b6-81da-13c1130c691a",
    "name": "California Facility 1"
  },
  "created": "2024-09-10T14:22:00.000000",
  "updated": "2024-09-10T14:22:00.000000"
}

document.updated.v2

Sent when an existing document is reprocessed or updated and its data changes. Common triggers include bill corrections, meter assignment changes, and usage data updates via the API. The event fires only when the document data actually differs — no-op updates are ignored. The payload includes old with previous field values so you can see what changed.
{
  "eventType": "document.updated.v2",
  "old": {
    "updated": "2024-09-10T14:22:00.000000"
  },
  "id": "b2d4e6f8-1234-5678-9abc-def012345678",
  "company": {
    "externalId": "269350a4-8595-42cc-96ee-bf047d093505",
    "id": "91c21c6b-5f3f-4d5f-9fb9-02530ef4b13c",
    "name": "Demo Company",
    "publicId": "cb78b85c-e68e-48de-a99e-e88862076823"
  },
  "site": {
    "id": "67e72ddf-9e9c-42b6-81da-13c1130c691a",
    "name": "California Facility 1"
  },
  "created": "2024-09-10T14:22:00.000000",
  "updated": "2024-09-12T08:15:00.000000"
}

document.deleted.v2

Sent when a document is deleted via the API or the platform. The payload contains the full document state at the time of deletion so you can identify which document was removed.
{
  "eventType": "document.deleted.v2",
  "id": "b2d4e6f8-1234-5678-9abc-def012345678",
  "company": {
    "externalId": "269350a4-8595-42cc-96ee-bf047d093505",
    "id": "91c21c6b-5f3f-4d5f-9fb9-02530ef4b13c",
    "name": "Demo Company",
    "publicId": "cb78b85c-e68e-48de-a99e-e88862076823"
  },
  "site": {
    "id": "67e72ddf-9e9c-42b6-81da-13c1130c691a",
    "name": "California Facility 1"
  },
  "created": "2024-09-10T14:22:00.000000",
  "updated": "2024-09-10T14:22:00.000000"
}

Signature verification

Verify webhook signatures to confirm that messages are genuinely sent by Nectar. For background on why this matters, see Why verify webhooks. Svix provides libraries that make verification straightforward:
import { Webhook } from "svix";

const secret = "whsec_your_signing_secret";

const headers = {
"svix-id": "msg_your_message_id",
"svix-timestamp": "1614265330",
"svix-signature": "v1,your_signature_here",
};
const payload = '{"test": 2432232314}';

const wh = new Webhook(secret);
const verified = wh.verify(payload, headers);

For additional languages and details, see the Svix verification documentation.

Retry schedule

Svix uses exponential backoff to retry failed deliveries. Each period starts after the preceding attempt fails:
AttemptDelay
1Immediately
25 seconds
35 minutes
430 minutes
52 hours
65 hours
710 hours
810 hours
If an endpoint is removed or disabled, remaining delivery attempts are cancelled.

Troubleshooting

Not using the raw payload body

This is the most common issue. Signature verification uses the raw string body of the message payload. If you serialize the JSON with methods like JSON.stringify, the output may differ from the original payload and cause verification to fail. Always verify the payload exactly as received, byte-for-byte.

Missing the secret key

Each endpoint has a unique signing secret. Confirm you’re using the correct key for the endpoint receiving the webhook.

Sending the wrong response codes

A 2xx status code signals successful delivery regardless of what the response body contains. Return the appropriate status code so the system knows whether delivery succeeded or failed.

Responses timing out

Any endpoint that doesn’t respond within the timeout window is treated as a failed delivery. If your endpoint processes complex workflows, receive the message, enqueue it for async processing, and return 200 immediately.

Failure recovery

Re-enable a disabled endpoint

If all delivery attempts to an endpoint fail over a 5-day period, the endpoint is automatically disabled. To re-enable it, open the webhook portal, find the endpoint, and select Enable Endpoint.

Replay failed messages

Use replay when your service experienced downtime or an endpoint was misconfigured.
  • Single message: Find the message in the portal, open the options menu next to any attempt, and click Resend.
  • Bulk recovery: On the endpoint details page, select Options > Recover Failed Messages and choose a time window. For more precision, open the options menu on any message and select Replay all failed messages since this time.

Connection statuses

All connection and account status values

Document upload

Upload bills for processing and track job status

Sandbox testing

Test webhook events with mock data