# Agencies and SaaS (/docs/concepts/multi-tenant)



FeedHorizon is built for posting on behalf of others. One organization holds all your clients or customers, each in their own profile, and you pay per connected account, not per client.

One profile per customer [#one-profile-per-customer]

Create a profile for every customer, brand or client. A profile keeps its accounts, posts, queue and time zone apart from the others.

```bash title="cURL"
curl -X POST https://feedhorizon.com/api/v1/profiles \
  -H "Authorization: Bearer fh_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Soup Club", "timezone": "Europe/Berlin", "externalId": "cus_8812" }'
```

Put your own customer id in `externalId`. It is unique in your organization, so you never have to store our ids: `GET /profiles?externalId=cus_8812` finds the profile again. Creating profiles needs a key with access to all profiles.

Let customers connect their own accounts [#let-customers-connect-their-own-accounts]

You do not need anyone's password. Create a [connect link](/docs/guides/connect-links) for the profile and the platform and send it to the customer, or open it inside your app. They sign in at the platform, and the account lands in their profile. You hear about it through the `account.connected` webhook.

Keys per customer or per service [#keys-per-customer-or-per-service]

| Setup                                                                          | Key                                                                 |
| ------------------------------------------------------------------------------ | ------------------------------------------------------------------- |
| Your backend talks to FeedHorizon for all customers                            | One key with access to all profiles                                 |
| A customer, a freelancer or a separate service should only reach some profiles | A key limited to those profiles (`fullAccess: false`, `profileIds`) |
| A dashboard or report that only reads                                          | A key with `permission: "readonly"`                                 |

A key limited to profiles sees nothing outside them: other profiles' posts and accounts answer `404` as if they did not exist. See [Authentication](/docs/api/authentication#profile-scope).

Team members [#team-members]

People in the dashboard are members of the organization. Owners and admins see every profile. A member can be limited to some profiles, and an AI assistant they connect over [MCP](/docs/mcp) is limited the same way.

Webhooks for all customers [#webhooks-for-all-customers]

Webhooks belong to the organization, so one endpoint gets the events of every profile. Each event carries `profileId`; look up the customer by it, or by the profile's `externalId`.

When a customer leaves [#when-a-customer-leaves]

* `DELETE /accounts/{id}` disconnects one account. Its scheduled posts are deleted with it, posts already live stay on the platform.
* `DELETE /profiles/{id}` deletes the profile with its accounts, posts and queue. The default profile cannot be deleted.

You pay only for connected accounts, so a disconnected account no longer counts, see [Pricing](/docs/pricing).

Next [#next]

[Recipe: Onboard a customer](/docs/recipes/onboard-a-customer) walks through these steps with code.
