Skip to content

View Data Source

When a view’s URL is configured under View settings → Configure URL and URL Active is on, the rendered view loads custom data from your endpoint. This page lists exactly what your endpoint receives and is allowed to return.

Interface Builder calls your endpoint server-side through its own backend, not directly from the user’s browser. The request always goes out as the OneClick app, signed with three reserved system headers.

Method Body sent? Use when
GET (default) No The endpoint expects context as URL query parameters only.
POST Yes The endpoint expects a JSON body with view context.

Configure under HTTP Method in the URL Configuration dialog.

The URL you write in the End-point URL field is processed before the request goes out:

  1. Placeholder substitution. Any title, name, id, api_key, or tier token is replaced with its resolved value. If the URL contains Pipedrive field placeholders, the builder waits for the Pipedrive fetch to finish first; otherwise it processes the URL immediately.
  2. Query parameters appended. Any Query parameters rows you added in the dialog, plus every search parameter from the user’s current view URL, are appended as ?key=value pairs.
  3. Whitespace warning. If the resolved URL still contains %20 in the path (typically because a placeholder resolved to an empty value), the builder shows a URL contains whitespace in path toast and still sends the request.

Every request carries:

Header Source Notes
x-oc-user-id The Pipedrive user who opened the view Always set, cannot be overridden.
x-oc-company-id The Pipedrive company Always set, cannot be overridden.
x-oc-event-id A short unique ID for this view-open event Always set, cannot be overridden. Use it to correlate logs.
OneClick-level headers The OneClick button’s own Headers toggle (Pipedrive’s Edit a Button page) Sent on every request when the toggle is on.
Per-call headers The dialog’s Manage Headers rows on this view Values accept * placeholders only.

Per-call header keys cannot collide with the three reserved keys above (x-oc-user-id, x-oc-company-id, x-oc-event-id) — those are dropped before the request goes out. Other x-oc-* keys are not reserved and pass through. See OneClick-Level Headers for the merge order.

{
"data": {
"view_name": "Account Summary"
},
"meta": {
"button_id": "btn-uuid",
"company_id": 6789,
"event_id": "aBcDeF",
"interface_view_id": "view-shortid",
"resource": "deal",
"resource_id": 1234,
"user_id": 12345
}
}
  • data.view_name — the view’s name. Useful when one endpoint serves several views and needs to switch on which view is asking.
  • meta — the same context block used by form submissions, so a single endpoint can read both flows the same way.

A floating window button has no Pipedrive record, so resource and resource_id are sent as null. Both keys stay in place, which keeps the body shape identical on both kinds of button:

{
"data": {
"view_name": "Account Summary"
},
"meta": {
"button_id": "btn-uuid",
"company_id": 6789,
"event_id": "aBcDeF",
"interface_view_id": "view-shortid",
"resource": null,
"resource_id": null,
"user_id": 12345
}
}

A missing record is null — never 0, never "".

The body collapses to an empty object:

{}

Use this only when the endpoint rejects unknown fields — e.g. Pipedrive API v2.

No request body. Instead, the same context that POST sends in the body is split between the URL and the headers:

Source Goes to Format
data.<key> URL query string ?data_<key>=<value>
meta.<key> Request headers x-oc-meta-<key>: <value> (kebab-cased)
User / company / event IDs Request headers x-oc-user-id, x-oc-company-id, x-oc-event-id

Example URL after substitution:

https://api.example.com/dashboard?data_view_name=Account%20Summary

Example headers — every meta key becomes its own header, so all seven are there:

x-oc-user-id: 12345
x-oc-company-id: 6789
x-oc-event-id: aBcDeF
x-oc-meta-button-id: btn-uuid
x-oc-meta-company-id: 6789
x-oc-meta-event-id: aBcDeF
x-oc-meta-interface-view-id: view-shortid
x-oc-meta-resource: deal
x-oc-meta-resource-id: 1234
x-oc-meta-user-id: 12345

Headers cannot carry null, and the string null would be a lie. So on a floating window button the two record headers are not sent at all — five x-oc-meta-* headers arrive instead of seven:

x-oc-user-id: 12345
x-oc-company-id: 6789
x-oc-event-id: aBcDeF
x-oc-meta-button-id: btn-uuid
x-oc-meta-company-id: 6789
x-oc-meta-event-id: aBcDeF
x-oc-meta-interface-view-id: view-shortid
x-oc-meta-user-id: 12345

Read the absence of the header as “there is no record”. Nothing is sent as 0 or an empty header value.

With Omit oneclick metadata on, the data_* query params and the x-oc-meta-* headers are skipped — only the three reserved system headers remain.

The endpoint’s response is parsed as JSON and stored under the active event ID. The view’s runtime polls for it and renders once the parsed object is available.

Return any JSON object. Every top-level field becomes a <field> placeholder in the Data Picker’s Custom tab.

{
"invoice_count": 3,
"balance_due": 4250.5,
"next_invoice": { "id": "INV-123", "due_date": "2026-06-01" }
}

The Data Picker exposes invoice_count, balance_due, next_invoice.id, and so on.

Return an oneclick_data.error_message envelope and the view shows a full-page message view instead of rendering blocks:

{
"oneclick_data": {
"error_message": {
"title": "Account not found",
"message": "We couldn't find that account. <a href=\"/accounts\">Choose another</a>."
}
}
}

The string form "error_message": "Something went wrong" works too. For a note that is not an error, send the same object as message_view. See HTTP Response Format → Error response for list messages, the optional variant, message_view, and the hideRetry and hideBack flags.

Send the user to a different view of the same interface:

{
"oneclick_data": {
"redirect_view": {
"id": "target-view-id",
"params": { "deal_id": "1234" }
}
}
}

The view shows a “Redirecting…” toast and navigates to the target. If id does not exist, it falls back to a full-page message view with View with ID … was not found.

See HTTP Response Format for the full schema.

Condition What the user sees
Endpoint returns a parsed JSON object inside ~20 s View renders with the data, * placeholders resolved.
Endpoint returns HTTP status 400 or higher Toast: Data loading failed (status N) plus whatever response body landed (rendered against the partial data).
Endpoint takes longer than ~20 s Toast: Request timed out. No custom data received. View renders without the custom data.
Endpoint throws a network error Full-page message view with the underlying error message.

The 20-second budget is a polling cap on the builder side, not a server-side fetch timeout. The actual server-side request to your endpoint runs as long as your endpoint takes; the polling layer just stops listening for a response after ~20 seconds.

The fetch is only triggered when the view runs in live rendering (what real Pipedrive users see) or in the builder’s Test mode. Preview mode does not call the data source URL — it renders against the saved Sample data instead. See External Data Flow for the load order, the parallel fetches, and the Test-mode overrides.