> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.runtype.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.runtype.com/_mcp/server.

# Quickstart: build a social media post generator as a REST API

Build a two-step Flow that fetches website content and generates social media posts. Attach the Flow to a Product and expose it through a REST API Surface.

## Before you begin

* Sign in to the [Runtype dashboard](https://use.runtype.com). Firecrawl is available through platform keys, so you do not need to add a provider API key for this quickstart.
* Optional: read [What are Flows?](/user-guide/flows/what-are-flows), [What are Products?](/user-guide/products-surfaces/what-are-products), and [What are Surfaces?](/user-guide/products-surfaces/what-are-surfaces).

## Create a Flow

To create the Flow, follow these steps:

1. On the **Flows** page, click **Create flow**.
2. Select **Start from scratch**.
3. Add a step with the **+** control.
4. Select **Fetch URL**.
5. In the **Fetch** selector, select **Firecrawl (Web Scraping)**.
6. In the **from URL** field, enter `{{website}}`. When you run the Flow, enter a value for `website`.
7. Add another step with the **+** control.
8. Select **Run Task**.
9. In the **User** editor, paste the following prompt:

**`Prompt`**

```text title="Prompt"
Here is website content:
{{fetch_result}}

Generate three social media posts for this article. Return a JSON object with these keys:
- "twitter" (under 280 characters)
- "linkedin" (2 to 3 paragraphs, professional tone)
- "instagram" (casual, with emoji suggestions)
```

10. Next to the model selector, click **Advanced settings**. The **Advanced Settings** panel opens.
11. Under **Response Format**, turn off **Use model default**. The format changes to **JSON**, so the endpoint returns the posts as a JSON object instead of a text string.
12. Set the Flow name to `Website Content to Social Media Content`.
13. Click **Create**.

Flow variables use double curly braces. The `{{website}}` expression reads the input named `website`, and `{{fetch_result}}` reads the output from the Fetch URL step. The Fetch URL step uses `fetch_result` as its default output variable. If you change that output variable, update the expression in the prompt.

For more information, read [Flow variables and templates](/user-guide/flows/flow-variables-and-templates).

## Test the Flow

To test the Flow before you create the Product, follow these steps:

1. In the Flow editor, click **Run flow**. The **Run Flow** panel opens.
2. In **Input Variables**, enter `https://example.com` as the value for `website`.
3. Click **Run Flow**.
4. Confirm that the response contains posts for Twitter, LinkedIn, and Instagram.

If the response does not contain all three posts, return to the **Run Task** step, edit the prompt, and run the Flow again.

## Create a Product and a Surface

A Product groups related Flows and Agents. A Capability makes a Flow or Agent available on a Product. A Surface exposes the Product through an interface, such as a REST API.

To create the Product and attach your Flow, follow these steps:

1. On the **Products** page, click **New product**.
2. Select **REST API**.
3. In the **Name** field, enter `Social Media Post Generator`.
4. Under **Add a capability to power your REST API**, select **Use Existing**.
5. Select **Flows**.
6. Select `Website Content to Social Media Content`.
7. Click **Create REST API**.

The Product includes your Flow as a Capability and a REST API Surface. The **Product editor** opens with the **Surface** panel open.

## Call the endpoint

The API Surface starts in draft mode and has no API key. To activate the Surface and create a key, follow these steps:

1. In the **Product editor**, open the **Overview** tab.
2. Set the status to **Active**. The Surface now accepts requests.
3. Open the **Keys** tab.
4. Click **Generate Key**.
5. In **Key Type**, select **Test**.
6. Click **Generate Key**.
7. Copy the generated key.
8. Open the **Endpoints** tab and copy the endpoint URL.

A **Test** key allows 50 requests per UTC day. For real traffic, generate a **Production** key. A Production key has no daily cap, but the dialog shows it only once, so copy or download it before you close the dialog. For more information, read [Authenticating with product API keys](/user-guide/products-surfaces/authenticating-with-product-api-keys).

To test the endpoint in the dashboard before you write code, follow these steps:

1. On the **Endpoints** tab, click the `Website Content to Social Media Content` endpoint.
2. In **Request Body**, enter `{"website": "https://example.com"}`.
3. Click **Run**. The response appears below the request body.

To browse and test every endpoint on the Surface, click **Interactive API docs**.

To call the endpoint from your code, send a `POST` request to the endpoint URL. The following TypeScript example sends the `website` input:

**`TypeScript`**

```typescript title="TypeScript"
const endpoint =
  'https://api.runtype.com/v1/products/YOUR_PRODUCT_ID/surfaces/YOUR_SURFACE_ID/api/website-content-to-social-media-content'

const response = await fetch(endpoint, {
  method: 'POST',
  headers: {
    Authorization: 'Bearer papi_YOUR_PRODUCT_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    website: 'https://example.com',
  }),
})

const data = await response.json()
console.log(data)
```

Use the following cURL command to send the same request:

**`cURL`**

```bash title="cURL"
curl -X POST \
  'https://api.runtype.com/v1/products/YOUR_PRODUCT_ID/surfaces/YOUR_SURFACE_ID/api/website-content-to-social-media-content' \
  -H 'Authorization: Bearer papi_YOUR_PRODUCT_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "website": "https://example.com"
  }'
```

Replace the following placeholders in both examples:

* `YOUR_PRODUCT_ID`: the Product ID in the endpoint URL
* `YOUR_SURFACE_ID`: the Surface ID in the endpoint URL
* `papi_YOUR_PRODUCT_KEY`: the full API key that you generated on the **Keys** tab

The last part of the URL is the endpoint slug. Runtype derives it from the Flow name, so the slug for this quickstart is `website-content-to-social-media-content` unless you changed it. If your slug is different, use the URL from the **Endpoints** tab.

The endpoint passes the request body to the Flow as input. By default, the response contains only the output of the last step. A successful response looks like the following example:

**`Response`**

```json title="Response"
{
  "twitter": "This domain is reserved for documentation examples. Use it freely.",
  "linkedin": "Example Domain is set aside for use in documentation...",
  "instagram": "Every guide needs a sample site. Meet example.com! ..."
}
```

To add execution metadata to the response or return a different step, change **Response Shape** or **Return Step** on the **Overview** tab. For more information, read [Setting up an API surface](/user-guide/products-surfaces/setting-up-an-api-surface).

To receive the output as Server-Sent Events while the Flow runs, add `?stream=true` to the endpoint URL. For the event format, read [Calling your API endpoints](/user-guide/products-surfaces/calling-your-api-endpoints).

## Troubleshoot

The following list describes common errors and how to fix them:

* **`401` with `API surface is not active`**: On the **Overview** tab, set the status to **Active**.
* **`401` with any other message**: Confirm that the `Authorization` header contains the full key, including the `papi_` prefix.
* **`429` with `Test Key Limit Exceeded`**: The Test key used its 50 requests for the day. Wait until midnight UTC, or generate a **Production** key.
* **The response is one string instead of a JSON object**: Set **Response Format** to **JSON** in the **Run Task** step, then call the endpoint again.

## Next steps

Continue with these guides:

* [Calling your API endpoints](/user-guide/products-surfaces/calling-your-api-endpoints): send requests, stream responses, and handle errors
* [Setting up an API surface](/user-guide/products-surfaces/setting-up-an-api-surface): configure authentication, status, and the response shape
* [Authenticating with product API keys](/user-guide/products-surfaces/authenticating-with-product-api-keys): manage Test and Production keys
* [Auto-generated OpenAPI spec](/user-guide/products-surfaces/auto-generated-openapi-spec): generate clients from the Surface specification
* [Quickstart: from Agent to chat widget](/user-guide/getting-started/quickstart-from-agent-to-chat-widget): expose an Agent through a chat Surface
* [Flow step types overview](/user-guide/flows/flow-step-types-overview): choose steps for more advanced Flows
* [What are Tools?](/user-guide/tools/what-are-tools): connect Flows and Agents to external systems
* [What are Logs?](/user-guide/logs/what-are-logs): inspect execution details and failures
* [Creating and managing records](/user-guide/records/creating-and-managing-records): add structured context to Flows
* [What are Evals?](/user-guide/evals/what-are-evals): compare prompts and models with the same inputs