---
title: hub.view | Doing Work API
description: The customer hub for the signed-in customer: their quotes, jobs, invoices with what is still owed, upcoming visits with any change request, and requests wi
url: https://doingwork.work/docs/reference/hub-view/
---

# hub.view

The customer hub for the signed-in customer: their quotes, jobs, invoices with what is still owed, upcoming visits with any change request, and requests with this shop. state is ok, gone (revoked, expired or unknown) or wrong_person (signed in with an email the shop does not have for this customer). Hosted page only.

|  |  |
|---|---|
| Who | Hosted page only (a person does it in the browser) |
| REST | `GET /v1/hub/view` |
| MCP tool | Not an MCP tool |
| Writes | no |
| Area | [Customer hub, requests and customer emails](https://doingwork.work/docs/reference/#customer-hub-requests-and-customer-emails) |

## When to use it

Give a customer one page with everything they have with the shop: hub.createLink makes a link for one customer (shown once; send it yourself, Doing Work sends nothing). On it the customer sees their quotes, jobs, invoices with what is still owed, upcoming visits and requests, opens a quote, pays an invoice, asks to move or cancel a visit, and asks for new work (it arrives as a portal request).

## What to tell the owner

Send the person the link. They finish this step themselves on the page; you never do it for them.

## Input

| Field | Type | Required |
|---|---|---|
| `k` | string | yes |

## Example

```http
GET https://doingwork.work/v1/hub/view?k=...
```

## Output

| Field | Type | Always there |
|---|---|---|
| `state` | string | yes |
| `link_id` | string (uuid) | no |
| `shop_id` | string (uuid) | no |
| `customer_id` | string (uuid) | no |
| `shop` | string | no |
| `customer` | string | no |
| `time_zone` | string | no |
| `expires_at` | string (date-time) | no |
| `properties` | array | no |
| `properties[].property_id` | string (uuid) | yes |
| `properties[].label` | ['string', 'null'] | yes |
| `properties[].address` | string | yes |
| `jobs` | array | no |
| `jobs[].job_id` | string (uuid) | yes |
| `jobs[].summary` | ['string', 'null'] | yes |
| `jobs[].status` | string | yes |
| `jobs[].created_at` | string (date-time) | yes |
| `quotes` | array | no |
| `quotes[].quote_id` | string (uuid) | yes |
| `quotes[].job_id` | string (uuid) | yes |
| `quotes[].summary` | ['string', 'null'] | yes |
| `quotes[].status` | string | yes |
| `quotes[].version` | integer | yes |
| `quotes[].total_minor` | integer | yes |
| `quotes[].currency` | string | yes |
| `quotes[].can_open` | boolean | yes |
| `invoices` | array | no |
| `invoices[].invoice_id` | string (uuid) | yes |
| `invoices[].job_id` | string (uuid) | yes |
| `invoices[].summary` | ['string', 'null'] | yes |
| `invoices[].status` | string | yes |
| `invoices[].total_minor` | integer | yes |
| `invoices[].balance_minor` | integer | yes |
| `invoices[].currency` | string | yes |
| `invoices[].can_pay` | boolean | yes |
| `visits` | array | no |
| `visits[].visit_id` | string (uuid) | yes |
| `visits[].job_id` | string (uuid) | yes |
| `visits[].summary` | ['string', 'null'] | yes |
| `visits[].title` | ['string', 'null'] | yes |
| `visits[].starts_at` | string (date-time) | yes |
| `visits[].ends_at` | string (date-time) | yes |
| `visits[].status` | string | yes |
| `visits[].can_ask_change` | boolean | yes |
| `visits[].change` | ['object', 'null'] | yes |
| `requests` | array | no |
| `requests[].request_id` | string (uuid) | yes |
| `requests[].title` | string | yes |
| `requests[].stage` | string | yes |
| `requests[].created_at` | string (date-time) | yes |

```json
{
  "state": "..."
}
```

## Errors

| Code | Status | What to do |
|---|---|---|
| `invalid_input`, `invalid_token`, `rate_limited` |  | Can happen on any call. See [errors](https://doingwork.work/docs/errors/). |
