> 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/api-guidelines.md).

# API Guidelines

Follow these standard guidelines when interacting with GrowSurf APIs.

## Requests

* All requests should be made using HTTPS.
* JSON objects are recommended for POST requests, but standard parameters are accepted.
* All parameters are required unless otherwise specified.

## Responses

* Data is returned in JSON.
* Any non-`200` HTTP response code can be considered an error.

{% hint style="info" %}
**Tip:** Refer to [Response Codes](/developer-tools/rest-api/api-response-codes.md) for help in troubleshooting any errors.
{% endhint %}

## Rate Limits

GrowSurf rate-limits all API requests, including client and server calls. Requests over a limit return a `429` in the format below.

API keys and OAuth connections for the same team share the team's aggregate rate limits. Creating more credentials does not increase the team's total request capacity.

```javascript
{
    "name": "RateLimit",
    "code": "RATE_LIMIT",
    "message": "You have reached your minute limit.",
    "status": 429,
    "supportUrl": "https://growsurf.com/settings#contact_support",
    "policyName": "MINUTE",
    "level": "error",
    "timestamp": "2019-12-08T00:05:45.478Z"
}
```

The `message` and `policyName` will indicate which limit you hit (e.g. second, minute, or hour).

### Rate Headers

{% hint style="info" %}
**NOTE:** Before authentication, the standard fields describe only the caller's public network budget. After authentication, they describe the API-key or OAuth connection and team budgets. The GrowSurf-specific fields are available only after authentication.
{% endhint %}

GrowSurf returns these machine-readable fields on REST responses:

| Header                 | Description                                                                                                                        |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| **`RateLimit-Policy`** | The active named quotas and their windows. For example, `"second";q=50;w=5` allows 50 requests per five-second window.             |
| **`RateLimit`**        | The remaining quota and seconds until reset. For example, `"second";r=12;t=3` means 12 requests remain for the next three seconds. |
| **`Retry-After`**      | The whole number of seconds to wait after a `429` response. This value takes precedence over `RateLimit`.                          |

`RateLimit-Policy` and `RateLimit` follow the current IETF HTTPAPI RateLimit header draft. `Retry-After` follows RFC 9110.

The following GrowSurf-specific fields remain available for backward compatibility:

| Header                                         | Description                                                                                                                                                                                                                                                                                                |
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`GrowSurf-RateLimit-Second-Limit`**          | The number of API requests that are allowed per second.                                                                                                                                                                                                                                                    |
| **`GrowSurf-RateLimit-Second-Remaining`**      | The number of API requests remaining within the second policy.                                                                                                                                                                                                                                             |
| **`GrowSurf-Retry-After-Second-Milliseconds`** | <p>The window of time that the <code>GrowSurf-RateLimit-Second-Limit</code> and <code>Growsurf-RateLimit-Second-Remaining</code> headers apply to.<br><br>For example, a value of 1000 would be a window of 1 second.</p><p>This value is only provided if the second policy is hit or exceeded.</p>       |
| **`GrowSurf-RateLimit-Minute-Limit`**          | The number of API requests that are allowed per minute.                                                                                                                                                                                                                                                    |
| **`GrowSurf-RateLimit-Minute-Remaining`**      | The number of API requests remaining within the minute policy.                                                                                                                                                                                                                                             |
| **`GrowSurf-Retry-After-Minute-Milliseconds`** | <p>The window of time that the <code>GrowSurf-RateLimit-Minute-Limit</code> and <code>Growsurf-RateLimit-Minute-Remaining</code> headers apply to.<br></p><p>For example, a value of 10000 would be a window of 10 seconds.</p><p>This value is only provided if the minute policy is hit or exceeded.</p> |
| **`GrowSurf-RateLimit-Hour-Limit`**            | The number of API requests that are allowed per hour.                                                                                                                                                                                                                                                      |
| **`GrowSurf-RateLimit-Hour-Remaining`**        | The number of API requests remaining within the hour policy.                                                                                                                                                                                                                                               |
| **`GrowSurf-Retry-After-Hour-Milliseconds`**   | <p>The window of time that the <code>GrowSurf-RateLimit-Hour-Limit</code> and <code>Growsurf-RateLimit-Hour-Remaining</code> headers apply to.<br></p><p>For example, a value of 600000 would be a window of 10 minutes.</p><p>This value is only provided if the hour policy is hit or exceeded.</p>      |

### Policies

The following are the rate limits for all API requests made using an API key.

| Policy     | Limit                   |
| ---------- | ----------------------- |
| **Second** | 50 requests / 5 seconds |
| **Minute** | 400 requests / minute   |
| **Hour**   | 20,000 requests / hour  |

### Slowdown Rate

For operations which update a resource (`PATCH`, `POST`, `DELETE`), if the cumulative rate of requests exceed 60 requests per minute, a slowdown delay will be added to each request thereafter. The delay is equal to the number of exceeded requests multiplied by 100 milliseconds (ms).

**For example:**

* 61st request: 100ms delay
* 63rd request: 300ms delay
* 70th request: 1000ms delay

### Max Connections

In addition to the rate limits and slowdown rate, the number of concurrent connections to the REST API allowed per IP address is limited to three (3).

If you hit a rate limit or max connection limit, you will see a [`429` error](/developer-tools/rest-api/api-response-codes.md#glossary).

### Suggestions

Here are some suggestions for using the GrowSurf API within policy limits.

#### 1. Cache data for repeat calls

If your site or app loads GrowSurf data on each page load, cache it. Cache repeated participant or program lookups too.

#### 2. Use Webhooks to get updated data from GrowSurf

Webhooks send your app updated data, so you do not need to poll GrowSurf. See [Webhooks](/developer-tools/webhooks.md) and [webhook examples](https://docs.growsurf.com/developer-tools/webhooks/examples).

## Metadata

Certain GrowSurf objects, such as [`Participants`](/developer-tools/rest-api/api-objects.md#participant) and [`Rewards`](/developer-tools/rest-api/api-objects.md#reward) can have a `metadata` field for storing your own data.

Learn more here:

{% content-ref url="/pages/KdcA4HSS8K9pL0VdjLEP" %}
[Metadata](/developer-tools/metadata.md)
{% endcontent-ref %}


---

# 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/api-guidelines.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.
