# OneForm for developers | OneForm

> Build on OneForm: a REST API for forms, links and invites, signed webhooks for every event, embeds for any website, an MCP server for AI agents, OAuth…

Source: https://oneform.si/developers/

---

1. [Home](https://oneform.si/)
2. Developers

[View as Markdown](https://oneform.si/developers.md)

Developers

# Build on OneForm.

Connect OneForm to the rest of your firm's tools. Read forms and send them to clients over a REST API, get every submission, report and booking as a signed webhook, put a form on any website, and let AI agents work in OneForm on your behalf.

[Get an API key](https://app.oneform.si/settings/api)[Download OpenAPI](https://oneform.si/developers/openapi.json)

## Quick start

Three steps from nothing to receiving every new submission at your own URL.

Make an API key

In OneForm, open [Settings → API keys](https://app.oneform.si/settings/api) and make a key (owners and admins can). It starts with `of_` and is shown once, so keep it somewhere safe, such as an environment variable:

Shell

```bash
export ONEFORM_API_KEY="of_…"
```

Check the key

`GET /me` answers with the firm and key the call was made with.

curl

```bash
curl https://app.oneform.si/api/v1/me \  -H "Authorization: Bearer $ONEFORM_API_KEY"
```

Node

```js
const res = await fetch("https://app.oneform.si/api/v1/me", {  headers: {    Authorization: `Bearer ${process.env.ONEFORM_API_KEY}`,  },});if (!res.ok) throw new Error(`OneForm answered ${res.status}: ${await res.text()}`);const data = await res.json();
```

Python

```python
import osimport requests res = requests.get(    "https://app.oneform.si/api/v1/me",    headers={"Authorization": f"Bearer {os.environ['ONEFORM_API_KEY']}"},    timeout=30,)res.raise_for_status()data = res.json()
```

PHP

```php
<?php$ch = curl_init("https://app.oneform.si/api/v1/me");curl_setopt_array($ch, [    CURLOPT_CUSTOMREQUEST => "GET",    CURLOPT_HTTPHEADER => [        "Authorization: Bearer " . getenv("ONEFORM_API_KEY"),    ],    CURLOPT_RETURNTRANSFER => true,]);$data = json_decode(curl_exec($ch), true);$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
```

Go

```go
package main import (	"fmt"	"io"	"net/http"	"os") func main() {	req, err := http.NewRequest("GET", "https://app.oneform.si/api/v1/me", nil)	if err != nil {		panic(err)	}	req.Header.Set("Authorization", "Bearer "+os.Getenv("ONEFORM_API_KEY"))	res, err := http.DefaultClient.Do(req)	if err != nil {		panic(err)	}	defer res.Body.Close()	out, _ := io.ReadAll(res.Body)	fmt.Println(res.Status, string(out))}
```

Ruby

```ruby
require "net/http"require "json" uri = URI("https://app.oneform.si/api/v1/me")req = Net::HTTP::Get.new(uri)req["Authorization"] = "Bearer #{ENV.fetch('ONEFORM_API_KEY')}"res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }data = JSON.parse(res.body)
```

Subscribe to an event

Give OneForm a public https URL and a trigger. From then on, every matching event is POSTed to it as JSON, signed with your firm's webhook secret.

curl

```bash
curl -X POST https://app.oneform.si/api/v1/hooks \  -H "Authorization: Bearer $ONEFORM_API_KEY" \  -H "Content-Type: application/json" \  -d '{  "target_url": "https://example.com/oneform/webhook",  "trigger": "form_submitted"}'
```

Node

```js
const res = await fetch("https://app.oneform.si/api/v1/hooks", {  method: "POST",  headers: {    Authorization: `Bearer ${process.env.ONEFORM_API_KEY}`,    "Content-Type": "application/json",  },  body: JSON.stringify({    "target_url": "https://example.com/oneform/webhook",    "trigger": "form_submitted"  }),});if (!res.ok) throw new Error(`OneForm answered ${res.status}: ${await res.text()}`);const data = await res.json();
```

Python

```python
import osimport requests res = requests.post(    "https://app.oneform.si/api/v1/hooks",    headers={"Authorization": f"Bearer {os.environ['ONEFORM_API_KEY']}"},    json={        "target_url": "https://example.com/oneform/webhook",        "trigger": "form_submitted",    },    timeout=30,)res.raise_for_status()data = res.json()
```

PHP

```php
<?php$ch = curl_init("https://app.oneform.si/api/v1/hooks");curl_setopt_array($ch, [    CURLOPT_CUSTOMREQUEST => "POST",    CURLOPT_HTTPHEADER => [        "Authorization: Bearer " . getenv("ONEFORM_API_KEY"),        "Content-Type: application/json",    ],    CURLOPT_POSTFIELDS => json_encode([        "target_url" => "https://example.com/oneform/webhook",        "trigger" => "form_submitted",    ]),    CURLOPT_RETURNTRANSFER => true,]);$data = json_decode(curl_exec($ch), true);$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
```

Go

```go
package main import (	"fmt"	"io"	"net/http"	"os"	"strings") func main() {	body := strings.NewReader(`{	  "target_url": "https://example.com/oneform/webhook",	  "trigger": "form_submitted"	}`)	req, err := http.NewRequest("POST", "https://app.oneform.si/api/v1/hooks", body)	if err != nil {		panic(err)	}	req.Header.Set("Authorization", "Bearer "+os.Getenv("ONEFORM_API_KEY"))	req.Header.Set("Content-Type", "application/json")	res, err := http.DefaultClient.Do(req)	if err != nil {		panic(err)	}	defer res.Body.Close()	out, _ := io.ReadAll(res.Body)	fmt.Println(res.Status, string(out))}
```

Ruby

```ruby
require "net/http"require "json" uri = URI("https://app.oneform.si/api/v1/hooks")req = Net::HTTP::Post.new(uri)req["Authorization"] = "Bearer #{ENV.fetch('ONEFORM_API_KEY')}"req["Content-Type"] = "application/json"req.body = JSON.generate({  "target_url" => "https://example.com/oneform/webhook",  "trigger" => "form_submitted",})res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }data = JSON.parse(res.body)
```

Next: [verify the signature](https://oneform.si/developers/webhooks/#verify), then see [every endpoint](https://oneform.si/developers/api/).

## What you can build with

[REST APIForms, links, invites and hooks.](https://oneform.si/developers/api/)[WebhooksSigned events, retries, payloads.](https://oneform.si/developers/webhooks/)[EmbedPut a form on any site.](https://oneform.si/developers/embed/)[AI agents (MCP)Claude, ChatGPT, Cursor and more.](https://oneform.si/developers/mcp/)[OAuthSign in with OneForm.](https://oneform.si/developers/oauth/)[ZapierNo-code triggers and actions.](https://oneform.si/developers/zapier/)[Form schemaThe form definition, as JSON Schema.](https://oneform.si/developers/form-schema/)

## At a glance

Base URL

`https://app.oneform.si/api/v1`

Authentication

`Authorization: Bearer of_…` or `X-API-Key`

Rate limit

120 calls a minute per key; 429 with Retry-After over it

Format

JSON over HTTPS. Errors are { error, code }

Version

v1, in the path. [OpenAPI 3.1](https://oneform.si/developers/openapi.json)

Webhooks

Signed with HMAC-SHA256, retried up to 8 tries

Limits per firm

25 API keys, 100 subscriptions, 300 form invites a day

AI agents

MCP at `https://app.oneform.si/mcp`

## Which credential to use

| Credential                   | For                                       | Belongs to                                | Made in                                                      |
| ---------------------------- | ----------------------------------------- | ----------------------------------------- | ------------------------------------------------------------ |
| API key of\_…                | The REST API and Zapier                   | The firm (acts for the admin who made it) | Settings → API keys                                          |
| Agent token ofp\_…           | The MCP server                            | One person in one firm                    | Settings → AI agents                                         |
| OAuth tokens ofa\_… / ofr\_… | The MCP server, for AI tools that sign in | One person in one firm                    | [Sign in with OneForm](https://oneform.si/developers/oauth/) |

API keys don't work on the MCP server, and agent tokens don't work on the REST API.

[Next →REST API](https://oneform.si/developers/api/)

Questions about the API, webhooks or embeds? [Ask a developer](https://oneform.si/contact/?topic=developers).

DevelopersOverview
- [Overview](https://oneform.si/developers/)
- [REST API](https://oneform.si/developers/api/)
- [Webhooks](https://oneform.si/developers/webhooks/)
- [Embed](https://oneform.si/developers/embed/)
- [AI agents (MCP)](https://oneform.si/developers/mcp/)
- [OAuth](https://oneform.si/developers/oauth/)
- [Zapier](https://oneform.si/developers/zapier/)
- [Form schema](https://oneform.si/developers/form-schema/)

Developers

- [Overview](https://oneform.si/developers/)
- [REST API](https://oneform.si/developers/api/)
- [Webhooks](https://oneform.si/developers/webhooks/)
- [Embed](https://oneform.si/developers/embed/)
- [AI agents (MCP)](https://oneform.si/developers/mcp/)
- [OAuth](https://oneform.si/developers/oauth/)
- [Zapier](https://oneform.si/developers/zapier/)
- [Form schema](https://oneform.si/developers/form-schema/)

[OpenAPI spec](https://oneform.si/developers/openapi.json)[Ask a developer](https://oneform.si/contact/?topic=developers)
