> For the complete documentation index, see [llms.txt](https://docs.growsurf.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.growsurf.com/developer-tools/rest-api.md).

# REST API

Use the REST API to create and manage your GrowSurf programs, participants, referrals, rewards, webhooks, and team settings from a secure server-side environment.

{% hint style="info" %}

* **Using AI?** Follow [Build with AI](/build-with-ai.md). It gives you prompts to copy and keeps account creation, email verification, and draft review under your control. Your assistant chooses the supported connection method.
* **Using TypeScript, Python, PHP, Ruby, or Java?** Use an official GrowSurf API library. [Learn more](https://docs.growsurf.com/developer-tools/rest-api/api-libraries).
* **Building a native iOS or Android app?** Use the [iOS SDK](/developer-tools/ios-sdk.md) or [Android SDK](/developer-tools/android-sdk.md) for mobile attribution, participant creation, sharing, and referral or affiliate portal data. Use the REST API from your backend for secure server-side actions.
  {% endhint %}

## Getting started

### Starting without a GrowSurf account

If you want an AI assistant to create your account, follow [Build with AI](/build-with-ai.md).

If you are implementing account creation yourself, use [`POST /accounts`](https://docs.growsurf.com/developer-tools/rest-api/api-reference#post-accounts). This endpoint does not need an API key. It requires a business email address and starts a 14-day Business trial without a credit card.

GrowSurf returns the first API key once. Store it in a secret manager. Do not put it in chat, logs, screenshots, URLs, analytics, or source files. Protected API calls return `403` with `EMAIL_NOT_VERIFIED_ERROR` until you verify your email address. Verifying unlocks that same key, so keep it and retry the call. GrowSurf deletes unverified accounts after 7 days. Signing in to the dashboard for the first time replaces this key; verifying your email does not.

After you verify your email, use `POST /campaigns` to create a program. New programs start in `DRAFT`. Keep the program in `DRAFT` until you separately approve launch, reward delivery, and payment changes.

{% hint style="info" %}
**Note:** The GrowSurf REST API is available to the following types of programs (campaigns):

* **Referral programs:** Users on a GrowSurf paid subscription plan
* **Affiliate programs:** Users who have a valid payment method on file
  {% endhint %}

### Step 1: Get your API key

1. Go to [API Keys in GrowSurf Settings](https://app.growsurf.com/settings#api-keys).
2. Create an API key.
3. Copy the new key when GrowSurf shows it. For security, the full key is shown only once.

{% hint style="warning" %}
**Important Tips:**

* Your API key holds many privileges, so keep it secure. Do not share your API key in publicly accessible areas such as GitHub, Bitbucket, web browsers, or frontend client code.
* Anyone who finds your key in browser code can make requests as you.
* Do not embed your REST API key in native mobile apps. Native iOS and Android apps should use the Mobile SDKs with a public Mobile SDK key. Keep REST API calls on your backend, especially calls that credit a referral after a purchase or subscription.
  {% endhint %}

***

### Step 2: Set up authentication

The GrowSurf REST API uses your API key to authenticate requests:

1. Set a plain text header named `Authorization` with the contents `Bearer <YOUR_API_ACCESS_KEY>`, where `<YOUR_API_ACCESS_KEY>` is your API key.

#### Example Authenticated Request

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X "GET" "https://api.growsurf.com/v2/campaign/4pdlhb" -H "Authorization: Bearer <YOUR_API_ACCESS_KEY>"
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://api.growsurf.com/v2/campaign/4pdlhb")
  .get()
  .addHeader("Authorization", "Bearer <YOUR_API_ACCESS_KEY>")
  .build();

Response response = client.newCall(request).execute();
```

{% endtab %}

{% tab title="Node.js 18+" %}

```javascript
async function getCampaign() {
  const response = await fetch("https://api.growsurf.com/v2/campaign/4pdlhb", {
    headers: {
      Authorization: "Bearer <YOUR_API_ACCESS_KEY>"
    }
  });
  const body = await response.json();

  if (!response.ok) {
    throw new Error(body.message || `GrowSurf request failed (${response.status})`);
  }

  console.log(body);
}

getCampaign();
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.growsurf.com/v2/campaign/4pdlhb"
headers = {
    'Authorization': "Bearer <YOUR_API_ACCESS_KEY>"
    }
response = requests.request("GET", url, headers=headers)

print(response.text)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$request = new HttpRequest();
$request->setUrl('https://api.growsurf.com/v2/campaign/4pdlhb');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
  'Authorization' => 'Bearer <YOUR_API_ACCESS_KEY>'
));

try {
  $response = $request->send();
  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
	"fmt"
	"net/http"
	"io/ioutil"
)

func main() {
	url := "https://api.growsurf.com/v2/campaign/4pdlhb"
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Add("Authorization", "Bearer <YOUR_API_ACCESS_KEY>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)
	fmt.Println(res)
	fmt.Println(string(body))

}
```

{% endtab %}
{% endtabs %}

#### Scoped Access

If a scoped key does not include the required scope or program access for a request, the API returns `403`. You can change API key scopes from your [Settings](https://app.growsurf.com/settings#api-keys) page. Choose only the access that your API key needs:

| Scope                | Access                                                                                                                                                                           |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `team:read`          | Read the selected team's name and GrowSurf verification state.                                                                                                                   |
| `team:write`         | Update the team name, request team verification, or resend the team owner verification email.                                                                                    |
| `api_key:rotate`     | Rotate the API key making the direct REST/SDK request. This scope and action are not available in MCP.                                                                           |
| `program:read`       | Read programs, program resources, reward configuration, emails, installation, options, design, and webhooks.                                                                     |
| `program:write`      | Create, clone, and update programs; create, update, or delete reward configuration, program resources, and webhooks; issue program resource upload tickets.                      |
| `participant:read`   | Read participants, referrals, leaderboards, participant activity, affiliate applications, and affiliate invites.                                                                 |
| `participant:write`  | Create and update participants, trigger or cancel referrals, and send participant emails or invites; review affiliate applications; create, resend, or revoke affiliate invites. |
| `participant:delete` | Delete participants in one request or in bulk.                                                                                                                                   |
| `reward:read`        | Read issued rewards, commissions, and payouts.                                                                                                                                   |
| `reward:write`       | Record or refund sales and approve commissions or rewards without fulfilling them.                                                                                               |
| `reward:delete`      | Delete issued rewards or commissions.                                                                                                                                            |
| `reward:fulfill`     | Fulfill an issued reward. This is separate because fulfillment may deliver something of value.                                                                                   |
| `analytics:read`     | Read aggregate program and participant analytics.                                                                                                                                |

Approving a reward requires `reward:write`. Approving and fulfilling it in the same request requires both `reward:write` and `reward:fulfill`.

***

## Base URL

All endpoints for the GrowSurf REST API start with the same base URL:

```
https://api.growsurf.com/v2
```

***

## **Next steps**

* [View Tutorials](/developer-tools/rest-api/tutorials.md)
* [View Objects](/developer-tools/rest-api/api-objects.md)
* [View API Reference](/developer-tools/rest-api/api-reference.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.growsurf.com/developer-tools/rest-api.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `build a script that syncs our docs to a CMS` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
