# Connections that last

September 13, 2026 · API

Before this release, the moment a provisioned person signed in to Layout on their own, your application lost the ability to build for them. Now the connection lasts until the person ends it.

## What changed

- **Durable connections.** Once a person is connected, you keep building carts for them after they open the Layout app, add a card, or sign in anywhere else. Every charge is still theirs to approve.
- **Existing Layout accounts can connect.** An account that already exists is attached to you only when its owner approves, on the same consent screen a Layout AI assistant uses, while signed in with the very number you provisioned.
- **Layout sends the approval link.** By default Layout texts the owner a short approval link and you simply wait. Pass `connectDelivery: "developer"` to get the link and deliver it yourself.
- **The person stays in control.** Connected apps appear in their Layout account, where they can disconnect you at any time. After that, your next build for them is refused.

## Branch on `next`

`POST /v1/users` now tells you the one step left for each person:

| `next` | What you do |
| --- | --- |
| `verify` | A new number. Verify it headlessly, or send the person `handoffUrl`. |
| `awaiting_user_approval` | An existing account, and Layout has texted its owner. Nothing to send. |
| `connect` | An existing account where you deliver the link: send its owner to `connect.connectUrl`. |
| `connected` | Already connected. Start building. |

## Ask again later

`POST /v1/users/:id/connect` asks an existing account's owner for approval at any time. The approval link is good for ten minutes, and an optional `https` `returnUrl` brings them back to you afterwards.

```bash
curl -X POST https://api.layout.link/v1/users/usr_4b8e/connect \
  -H "Authorization: Bearer $LAYOUT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "returnUrl": "https://your.app/connected", "connectDelivery": "developer" }'

200 OK
{ "next": "connect", "connectUrl": "https://account.layout.link/authorize?request_id=…", "expiresInSec": 600 }
```

Leave out `connectDelivery` and Layout texts the person instead, answering `next: "awaiting_user_approval"` with a masked `awaitingApproval.phoneHint`. If the text cannot be sent, you get the link back so the person is never unreachable. A person already connected answers `connected: true`.

## Breaking changes

None for new connections. Code that treated `next` as only `verify` should handle all four values. A person who signed in before this release still needs to approve you once.
