Appearance
View Data Source
Type: Reference | Audience: Interface builder user and the backend developer your view talks to
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.
Request
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
| 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.
URL
The URL you write in the End-point URL field is processed before the request goes out:
- 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.
- 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=valuepairs. - Whitespace warning. If the resolved URL still contains
%20in the path (typically because a placeholder resolved to an empty value), the builder shows aURL contains whitespace in pathtoast and still sends the request.
Headers
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.
POST body
json
{
"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.
POST body from a floating window button
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:
json
{
"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 "".
POST body with Omit oneclick metadata on
The body collapses to an empty object:
json
{}Use this only when the endpoint rejects unknown fields — e.g. Pipedrive API v2.
GET request
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%20SummaryExample 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: 12345GET headers from a floating window button
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: 12345Read 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.
Response
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.
Plain data (typical case)
Return any JSON object. Every top-level field becomes a <field> placeholder in the Data Picker's Custom tab.
json
{
"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.
Error message
Return an oneclick_data.error_message envelope and the view shows a full-page message view instead of rendering blocks:
json
{
"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.
Redirect
Send the user to a different view of the same interface:
json
{
"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.
Timeout and status handling
| 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.
Where this runs
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.