# Publishing Agents

> Publish an agent to embed it on external sites. Visitors chat without signing in; your workspace pays for inference.

**URL:** https://inference.sh/docs/agents/publishing
**Last updated:** 2026-10-01

---

Publish an agent to embed it on external sites. Visitors chat without signing in; your workspace pays for inference.

---

## Publish from the web app

1. Open your agent in [Agents](https://app.inference.sh/agents).
2. Go to the **Publish** tab.
3. Turn on **Published**.

When published:

- The agent is available at an embed URL: `https://app.inference.sh/embed/agents/{namespace}/{name}`
- You receive an iframe snippet to paste into your site.
- **You pay for all inference costs** when others use the embedded agent.

Save the agent before publishing — the Publish tab is available only after the agent exists.

### A2A agent card (marketplace listings)

For [Agent2Agent (A2A)](https://a2a-protocol.org/latest/specification/) discovery and partner marketplaces (for example [GCP AI Agents Producer Portal](https://docs.cloud.google.com/marketplace/docs/partners/ai-agents)), open the agent detail page and click **a2a card** in the header to copy the agent card JSON to your clipboard.

The card's `url` field is the agent's A2A service endpoint (`https://api.inference.sh/agents/{namespace}/{name}/a2a`); `documentationUrl` points at the workspace page. The same payload is available via `GET /agents/{namespace}/{name}/card` — see [Agents API — Get A2A agent card](/docs/api/rest/agents#get-a2a-agent-card) and [A2A protocol](/docs/api/rest/agents#a2a-protocol).

### Publish via REST API

Automate publishing with the [Publications API](/docs/api/rest/publications). Create, update, and delete publications with an API key that has the `agents:write` scope:

```bash
# Publish an agent
curl -X POST https://api.inference.sh/publications \
  -H "Authorization: Bearer inf_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "resource_type": "agent",
    "resource_id": "agent_abc123"
  }'
```

List existing publications with `GET /publications?resource_type=agent&resource_id={agentId}` (`agents:read` scope). Ownership is enforced server-side: you can only publish agents your workspace can write.

---

## Allowed origins

Restrict which sites can load the embed in an iframe:

| Setting | Behavior |
|---------|----------|
| **Empty** | Any origin may embed (default) |
| **Comma-separated URLs** | Only matching `Origin` headers are accepted (for example `https://example.com`) |
| **`*` in the list** | Explicit wildcard — same as empty |

The API checks the browser `Origin` header on embed requests. Mismatched origins receive **403 Forbidden** (`origin not allowed`).

---

## Custom theme

Optional branding for the embedded chat UI:

- **Light mode** colors: primary, secondary, background, text, border
- **Dark mode** colors (optional): same fields

Theme colors are returned by `GET /embed/agents/{namespace}/{name}` and applied to the hosted embed page.

---

## Embed on your site

Copy the iframe snippet from the Publish tab:

```html
<iframe
  src="https://app.inference.sh/embed/agents/myteam/support-agent"
  width="400"
  height="600"
  style="border: none; border-radius: 12px;"
  allow="clipboard-write"
></iframe>
```

Replace `myteam/support-agent` with your agent's namespace and name.

For custom integrations (your own UI, host-page context, programmatic chat), use the [Embed API](/docs/api/rest/embed) instead of the hosted iframe.

---

## Host page context (optional)

When you build a custom embed UI, the host page can pass context into the iframe and receive actions back via `postMessage`.

**Host → embed** (send context after the iframe loads):

```javascript
iframe.contentWindow.postMessage({
  type: 'embed:context',
  payload: {
    url: window.location.href,
    userId: 'user_123',
    plan: 'pro',
  },
}, '*');
```

**Embed → host** (readiness and actions):

| Message | Direction | Purpose |
|---------|-----------|---------|
| `embed:ready` | embed → host | Iframe is listening for context |
| `embed:context` | host → embed | Merge key/value context for the agent |
| `embed:action` | embed → host | Agent invoked `send_to_host` (includes `id`, `action`, `params`) |
| `embed:action:result` | host → embed | Response to an action (`id`, `result`) |

Host context tools (`get_host_context`, `send_to_host`) are deprecated and disabled: agents are no longer offered them, so the `embed:action` messages above are not sent. A replacement for passing host page context to embedded agents is planned.

→ [Embed API](/docs/api/rest/embed) — REST endpoints and SDK client setup  
→ [Internal tools](/docs/api/agent/internal-tools#host-context-tools-deprecated) — host context (deprecated)

---

## Billing and limits

Embedded runs use the **publisher's workspace** for billing and entitlements. Anonymous visitors do not need API keys.

If the publisher's balance is insufficient, embed runs may return **402 Payment Required**.

---

## Related

- [Creating an Agent](/docs/agents/creating)
- [Publications API](/docs/api/rest/publications)
- [Embed API](/docs/api/rest/embed)
- [Client tools](/docs/api/agent/client-tools)
