Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/growsurf-com:growsurf-com-teams-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: GrowSurf REST Teams API
version: 2.0.0
description: 'Public GrowSurf REST API for managing programs, participants, referrals,
rewards, affiliate commissions, payouts, and analytics.
Every endpoint requires a GrowSurf REST API key in the `Authorization: Bearer `
header. To get one, sign up at https://app.growsurf.com, then create an API key in the GrowSurf
dashboard. You can create multiple API keys, with optional scopes and program access limits.
Each operation lists its required API-key scope in `x-growsurf-required-scopes`.
Team scopes cover team details and verification; program scopes cover program settings,
reward configuration, and webhooks; participant scopes cover participant records and
referrals; reward scopes cover sales, commissions, payouts, and issued rewards; and
analytics scope covers aggregate reporting. `api_key:rotate` is available only to direct
API-key REST/SDK clients and is unavailable through MCP. `reward:fulfill` is separate
because fulfillment may deliver something of value.
The team owner''s email address must be verified before the API can manage programs and their
resources. Until it is, those endpoints return a `403` with error code
`EMAIL_NOT_VERIFIED_ERROR`. Resend the owner verification email via
`POST /team/owner/verification-email`, then retry.
For agent-led onboarding, use the canonical Arazzo 1.1 workflow at
`https://growsurf.com/arazzo.yaml`. Starting from an API key the account owner created, it
configures and verifies a draft program. It never launches a program or performs a paid,
reward, payout, key-rotation, or destructive action.
REST responses include `RateLimit-Policy` and `RateLimit` fields so clients can throttle before
they reach a quota. Before authentication, these fields describe only the caller''s public
network budget. After authentication, they describe the credential and team budgets. A `429`
response also includes `Retry-After`; that value takes precedence when it is present. GrowSurf''s
legacy rate-limit fields remain available for backward compatibility.
GrowSurf versions this API in the URL and gives at least 12 calendar months of public notice
before a planned breaking removal. The notice period starts when the public OpenAPI schema marks
the affected surface as deprecated and GrowSurf publishes migration guidance. Urgent security,
privacy, legal, or service-integrity requirements can require a shorter window. See the public
lifecycle policy for the full rules and machine-readable signals.
Every REST response carries `Link: ; rel="deprecation"` (RFC 9745), which points at
that lifecycle policy. A surface that is actually deprecated adds a `Deprecation` field, and one
with a planned shutdown date adds a `Sunset` field (RFC 8594). No `Deprecation` field means the
surface is not deprecated.'
contact:
name: GrowSurf Support
url: https://growsurf.com/settings#contact_support
license:
name: Proprietary
url: https://growsurf.com/terms
x-deprecation-policy:
url: https://docs.growsurf.com/developer-tools/rest-api/api-lifecycle
versioning: URL path (/v2)
minimumNoticeMonths: 12
signals:
- 'Link: <https://docs.growsurf.com/developer-tools/rest-api/api-lifecycle>; rel="deprecation" (RFC 9745) on every response'
- Deprecation response field (RFC 9745) once a surface is deprecated
- Sunset response field (RFC 8594) once a shutdown date is planned
- 'deprecated: true in this OpenAPI document'
servers:
- url: https://api.growsurf.com/v2
description: Production
security:
- apiKeyAuth: []
tags:
- name: Teams
description: The team bound to an API key or OAuth connection.
paths:
/team:
get:
tags:
- Teams
operationId: getTeam
x-growsurf-required-scopes:
- team:read
summary: Retrieve team
description: Retrieves the team bound to the API key or OAuth connection. `verificationStatus` is `VERIFIED` once GrowSurf has verified the team, which is required before a program can send participant emails.
responses:
'200':
description: Team returned.
content:
application/json:
schema:
$ref: '#/components/schemas/Team'
examples:
default:
$ref: '#/components/examples/TeamExample'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/RateLimited'
patch:
tags:
- Teams
operationId: updateTeam
x-growsurf-required-scopes:
- team:write
summary: Update team
description: Updates the name of the team bound to the API key or OAuth connection. Any other property is rejected with a `400`. Personal profiles, billing, and team ownership are not editable here.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateTeamRequest'
examples:
default:
$ref: '#/components/examples/UpdateTeamRequestExample'
responses:
'200':
description: Updated team returned.
content:
application/json:
schema:
$ref: '#/components/schemas/Team'
examples:
default:
$ref: '#/components/examples/TeamExample'
'400':
$ref: '#/components/responses/BadRequest'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/RateLimited'
/team/verification-request:
post:
tags:
- Teams
operationId: requestTeamVerification
x-growsurf-required-scopes:
- team:write
summary: Request team verification
description: Requests GrowSurf to verify the bound team (required before a program can email its participants). Idempotent — calling it again while a request is pending does not create a duplicate. Returns the team with its updated `verificationStatus`.
responses:
'200':
description: Verification request recorded.
content:
application/json:
schema:
$ref: '#/components/schemas/Team'
examples:
default:
$ref: '#/components/examples/TeamExample'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/RateLimited'
/team/owner/verification-email:
post:
tags:
- Teams
operationId: resendTeamOwnerVerificationEmail
x-growsurf-required-scopes:
- team:write
summary: Resend team owner verification email
description: 'Resends the email-verification message to the owner of the account the API key belongs to. This is the recovery path for a `403` with error code `EMAIL_NOT_VERIFIED_ERROR`, so it stays callable with any GrowSurf API key while the rest of the API is locked. The response never reveals the owner''s email address. A `200` with `status: SENT` is returned only when an email was actually dispatched. Returns `400` if the email is already verified, and `429` if a verification email was sent too recently — wait a moment, then retry.'
responses:
'200':
description: Verification email sent.
content:
application/json:
schema:
$ref: '#/components/schemas/VerificationEmailResponse'
examples:
default:
$ref: '#/components/examples/VerificationEmailResponseExample'
'400':
$ref: '#/components/responses/BadRequest'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/RateLimited'
/api-key/rotate:
post:
tags:
- Teams
operationId: rotateApiKey
x-growsurf-required-scopes:
- api_key:rotate
x-growsurf-credential-types:
- TEAM_API_KEY
summary: Rotate API key
description: Generates a new API key and makes the key used on this request stop working when rotation succeeds. Send a unique, random `Idempotency-Key`. If the response is interrupted, immediately retry with the original API key and the same `Idempotency-Key` to receive the same new key. Update every integration that used the old key. The team owner is notified by email whenever the key is rotated. GrowSurf SDKs generate the idempotency key automatically. This endpoint accepts an API key with `api_key:rotate`. If this scope is unavailable, rotate the key in the authenticated dashboard instead. This operation is available only through the REST API or a GrowSurf API SDK, not through MCP.
parameters:
- name: Idempotency-Key
in: header
required: true
description: A unique, random value for this rotation request. Reuse this value only when retrying the same request with the original API key.
schema:
type: string
minLength: 8
maxLength: 255
pattern: ^[A-Za-z0-9._:-]+$
example: pied-piper-api-key-rotation-550e8400-e29b-41d4-a716-446655440000
responses:
'200':
description: The new API key.
content:
application/json:
schema:
$ref: '#/components/schemas/RotateApiKeyResponse'
examples:
default:
$ref: '#/components/examples/RotateApiKeyResponseExample'
'400':
$ref: '#/components/responses/BadRequest'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/RateLimited'
components:
responses:
BadRequest:
description: Invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Forbidden:
description: The API key is missing, invalid, revoked, outside its scope, or not allowed to perform this action.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
emailNotVerified:
summary: Account owner email verification is required
value:
name: EmailNotVerifiedError
code: EMAIL_NOT_VERIFIED_ERROR
message: The team owner email address must be verified to use this endpoint. Check the owner inbox, or resend it via POST /v2/team/owner/verification-email. Retry this request with the same API key once verified.
status: 403
missingCredential:
summary: No API key reached the API
value:
name: NotAuthorizedError
code: NOT_AUTHORIZED_ERROR
message: 'No API key provided. Send it as an Authorization: Bearer header.'
status: 403
invalidCredential:
summary: The API key was rejected
value:
name: NotAuthorizedError
code: NOT_AUTHORIZED_ERROR
message: The API key provided is not valid. It may have been rotated or revoked.
status: 403
notAuthorized:
summary: The credential cannot perform this action
value:
name: NotAuthorizedError
code: NOT_AUTHORIZED_ERROR
message: You are not authorized to perform this action.
status: 403
RateLimited:
description: Too many requests.
headers:
RateLimit-Policy:
description: Named quota policies, quotas, and windows using the IETF RateLimit Structured Fields format.
schema:
type: string
example: '"second";q=50;w=5, "minute";q=400;w=60, "hour";q=20000;w=3600'
RateLimit:
description: Remaining quota and reset time in seconds for the active policy or policies.
schema:
type: string
example: '"second";r=0;t=30'
Retry-After:
description: Whole seconds to wait before retrying this request. This field takes precedence over RateLimit.
schema:
type: string
pattern: ^[0-9]+$
example: '30'
GrowSurf-RateLimit-Second-Limit:
description: Number of API requests allowed per second policy.
schema:
type: integer
GrowSurf-RateLimit-Second-Remaining:
description: Number of API requests remaining in the second policy.
schema:
type: integer
GrowSurf-Retry-After-Second-Milliseconds:
description: Milliseconds until the second policy window resets.
schema:
type: integer
GrowSurf-RateLimit-Minute-Limit:
description: Number of API requests allowed per minute policy.
schema:
type: integer
GrowSurf-RateLimit-Minute-Remaining:
description: Number of API requests remaining in the minute policy.
schema:
type: integer
GrowSurf-Retry-After-Minute-Milliseconds:
description: Milliseconds until the minute policy window resets.
schema:
type: integer
GrowSurf-RateLimit-Hour-Limit:
description: Number of API requests allowed per hour policy.
schema:
type: integer
GrowSurf-RateLimit-Hour-Remaining:
description: Number of API requests remaining in the hour policy.
schema:
type: integer
GrowSurf-Retry-After-Hour-Milliseconds:
description: Milliseconds until the hour policy window resets.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
schemas:
RotateApiKeyResponse:
type: object
required:
- apiKey
properties:
apiKey:
type: string
description: The new API key. Store it now; the key used for rotation stops working immediately.
UpdateTeamRequest:
type: object
description: The Team fields you can update. Any property not listed here is rejected with a `400`.
additionalProperties: false
required:
- name
properties:
name:
description: The team's display name.
type: string
minLength: 1
maxLength: 255
Error:
type: object
properties:
name:
description: Error name returned for the failed request.
type: string
example: BadRequestError
code:
description: Stable machine-readable error code.
type: string
example: BAD_REQUEST_ERROR
message:
description: Human-readable error message.
type: string
example: Invalid request. Request params are missing or are invalid
errors:
description: Optional validation details for specific request fields.
type: array
items:
type: object
additionalProperties: true
example:
- field: email
message: Invalid email address.
status:
description: HTTP status code for the error.
type: integer
example: 400
supportUrl:
description: Support URL related to the error, when available.
type: string
format: uri
example: https://app.growsurf.com/settings#contact_support
policyName:
description: Rate-limit policy name for `429` errors, when available.
type: string
example: minute
level:
description: Error severity level, when available.
type: string
example: error
timestamp:
description: When the error response was created.
type: string
format: date-time
example: '2026-07-08T12:00:00.000Z'
example:
name: BadRequestError
code: BAD_REQUEST_ERROR
message: Invalid request. Request params are missing or are invalid
status: 400
supportUrl: https://app.growsurf.com/settings#contact_support
Team:
type: object
description: The team bound to the API key or OAuth connection.
required:
- name
- verificationStatus
- verificationRequestedAt
properties:
name:
description: The team's display name.
type: string
example: Pied Piper
verificationStatus:
type: string
enum:
- NOT_REQUESTED
- REQUESTED
- VERIFIED
readOnly: true
description: GrowSurf team verification state. `VERIFIED` is required before a program can send participant emails.
example: VERIFIED
verificationRequestedAt:
type:
- integer
- 'null'
format: int64
readOnly: true
description: When team verification was last requested, as a Unix timestamp in milliseconds.
example: 1719792000000
VerificationEmailResponse:
type: object
required:
- success
- status
properties:
success:
description: Whether the verification email request was accepted.
type: boolean
status:
description: Status of the verification email request.
type: string
enum:
- SENT
examples:
UpdateTeamRequestExample:
value:
name: Pied Piper Labs
RotateApiKeyResponseExample:
value:
apiKey: sk_api_0123456789abcdef0123456789abcdef_u9v4m2q8n6r5s1t7w3x0y9z8a6b4c2d0e1f3g5h7
TeamExample:
value:
name: Pied Piper
verificationStatus: VERIFIED
verificationRequestedAt: 1719792000000
VerificationEmailResponseExample:
value:
success: true
status: SENT
securitySchemes:
apiKeyAuth:
type: http
scheme: bearer
bearerFormat: API key
description: 'GrowSurf REST API key supplied as `Authorization: Bearer <api_key>`.'
externalDocs:
description: GrowSurf REST API lifecycle, versioning, and deprecation policy
url: https://docs.growsurf.com/developer-tools/rest-api/api-lifecycle