> 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

{% hint style="info" %}

* **Using AI?** If you're using an AI tool such as Cursor, Claude Code, Antigravity, or Codex to help you implement GrowSurf, we recommend utilizing our [MCP server](https://docs.growsurf.com/build-with-ai).
* **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 portal data. Use the REST API from your backend for secure server-side actions.
  {% endhint %}

## Getting started

{% 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.
* Do not use the RESTful API in browser applications. Exposing your secret API key within front end code exposes it to security risks. Anybody with a bit of programming knowledge could potentially hijack your API key and begin making requests on your behalf.
* 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 for purchase, subscription, or other server-verified referral qualification events.
  {% 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" %}

```javascript
const request = require("request");

const options = {
  method: 'GET',
  url: 'https://api.growsurf.com/v2/campaign/4pdlhb',
  headers: {
    Authorization: 'Bearer <YOUR_API_ACCESS_KEY>'
  }
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);
  console.log(body);
});
```

{% 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, reward configuration, emails, installation, options, design, and webhooks.              |
| `program:write`      | Create, clone, and update programs; create, update, or delete reward configuration and webhooks.       |
| `participant:read`   | Read participants, referrals, leaderboards, and participant activity.                                  |
| `participant:write`  | Create and update participants, trigger or cancel referrals, and send participant emails or 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 current page URL with the `ask` query parameter, and the optional `goal` query parameter:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
