Sponsorship API
API for programmatic management of partner sponsorship campaigns, links, and billing status
Partner Sponsorship API
The Partner Sponsorship API is for partner organizations that want to automate sponsorship campaigns, redemption links, and internal billing status tracking. Access requires both partnerSponsorship and partnerSponsorshipApi to be enabled for the partner organization.
This API does not include public validate or end-user redeem endpoints. The actual redemption step is only available through the in-app product flow.
Authentication
This API uses Organization API Keys. Keys are created by organization administrators, use the sk_meingpt_um_ prefix, and are sent as a Bearer token.
curl -X GET "https://app.meingpt.com/api/sponsorship/v1/campaigns" \
-H "Authorization: Bearer $MEINGPT_SPONSORSHIP_API_KEY"Rate Limiting
All organization API keys have a default rate limit of 100 requests per minute. Rate limit information is returned in response headers:
X-RateLimit-Limit: Maximum requests per windowX-RateLimit-Remaining: Remaining requestsX-RateLimit-Reset: Unix timestamp when the limit resets
Creating API Keys
Workspace admins create organization API keys in settings. See API & Key Management for setup details.
The clear-text key is shown only once. Store it securely.
Endpoints
List campaigns
GET /api/sponsorship/v1/campaigns?page=1&pageSize=50&status=active|inactive|allLists sponsorship campaigns for the partner organization with pagination.
Request fields
| Field | Location | Type | Required | Description |
|---|---|---|---|---|
page | Query | Integer | No | Page number, default 1 |
pageSize | Query | Integer | No | Items per page, default 50, maximum 100 |
status | Query | String | No | Filter active, inactive, or all, default all |
Response
{
"status": "success",
"campaigns": [
{
"id": "camp_123",
"name": "Spring promotion",
"durationMonths": 4,
"maxRedemptions": 250,
"expiresAt": "2026-06-30T23:59:59.000Z",
"includedSeats": 5,
"allowedEmailDomains": ["acme.com"],
"allowedEmails": ["alice@acme.com"],
"pricing": {
"model": "FIXED",
"amountEur": 5,
"unit": "PER_REDEMPTION"
},
"isActive": true,
"createdAt": "2026-04-01T08:00:00.000Z",
"updatedAt": "2026-04-10T12:15:00.000Z",
"completedRedemptionsCount": 18,
"reservedRedemptionsCount": 20
}
],
"total": 1,
"page": 1,
"pageSize": 50,
"totalPages": 1
}Error codes
400- Invalid query parameters401- Invalid or missing API key403- Feature not enabled or no access to the API404- Resource not found
Create campaign
POST /api/sponsorship/v1/campaignsCreates a new sponsorship campaign.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
name | String | Yes | Campaign name, 1 to 200 characters |
durationMonths | Integer | Yes | Sponsorship duration in months, integer from 1 to 6 |
maxRedemptions | Integer | No | Optional redemption cap, minimum 1 |
expiresAt | String (Date-Time) | No | Optional campaign expiry date |
includedSeats | Integer or null | No | Optional seat cap per sponsored organization, 1 to 1000 |
allowedEmailDomains | String array | No | Optional allowlist of email domains |
allowedEmails | String array | No | Optional allowlist of individual email addresses |
Response
{
"status": "success",
"campaign": {
"id": "camp_123",
"name": "Spring promotion",
"durationMonths": 4,
"maxRedemptions": 250,
"expiresAt": "2026-06-30T23:59:59.000Z",
"includedSeats": 5,
"allowedEmailDomains": ["acme.com"],
"allowedEmails": ["alice@acme.com"],
"pricing": null,
"isActive": true,
"createdAt": "2026-04-16T09:30:00.000Z",
"updatedAt": "2026-04-16T09:30:00.000Z",
"completedRedemptionsCount": 0,
"reservedRedemptionsCount": 0
}
}Error codes
400- Invalid request body401- Invalid or missing API key403- Feature not enabled or no access to the API404- Resource not found
Update campaign
PATCH /api/sponsorship/v1/campaigns/:campaignIdUpdates individual fields of an existing campaign.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
name | String | No | New campaign name, 1 to 200 characters |
durationMonths | Integer | No | New sponsorship duration, integer from 1 to 6 |
maxRedemptions | Integer or null | No | New cap. Use null to clear an existing cap; omit to leave unchanged |
expiresAt | String (Date-Time) or null | No | New expiry date. Use null to clear an existing date; omit to leave unchanged |
isActive | Boolean | No | Enables or disables the campaign |
includedSeats | Integer or null | No | New seat cap. Use null to clear the value |
allowedEmailDomains | String array | No | New domain allowlist |
allowedEmails | String array | No | New email allowlist |
Response
{
"status": "success",
"campaign": {
"id": "camp_123",
"name": "Spring promotion DACH",
"durationMonths": 5,
"maxRedemptions": null,
"expiresAt": null,
"includedSeats": 10,
"allowedEmailDomains": ["acme.com", "example.org"],
"allowedEmails": ["alice@acme.com"],
"pricing": {
"model": "FIXED",
"amountEur": 5,
"unit": "PER_REDEMPTION"
},
"isActive": true,
"createdAt": "2026-04-01T08:00:00.000Z",
"updatedAt": "2026-04-16T10:00:00.000Z",
"completedRedemptionsCount": 18,
"reservedRedemptionsCount": 20
}
}Error codes
400- Invalid request body401- Invalid or missing API key403- Feature not enabled or no access to the API404- Resource not found
List links for a campaign
GET /api/sponsorship/v1/campaigns/:campaignId/links?page=1&pageSize=100Lists sponsorship links for a campaign.
Request fields
| Field | Location | Type | Required | Description |
|---|---|---|---|---|
campaignId | Path | String | Yes | Campaign ID |
page | Query | Integer | No | Page number, default 1 |
pageSize | Query | Integer | No | Items per page, default 100, maximum 100 |
Response
{
"status": "success",
"links": [
{
"id": "link_123",
"name": "April landing page",
"token": "abcdef1234567890abcdef1234567890",
"url": "https://app.meingpt.com/auth?sponsored=abcdef1234567890abcdef1234567890",
"isActive": true,
"hasPassword": true,
"createdAt": "2026-04-16T10:15:00.000Z",
"completedRedemptionsCount": 7
}
],
"total": 1,
"page": 1,
"pageSize": 100,
"totalPages": 1
}Error codes
400- Invalid query parameters401- Invalid or missing API key403- Feature not enabled or no access to the API404- Resource not found
Create a link under a campaign
POST /api/sponsorship/v1/campaigns/:campaignId/linksCreates a new sponsorship link under a campaign.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
name | String | No | Optional display name for the link, 1 to 200 characters |
password | String | No | Optional link password, minimum 4 characters |
Response
{
"status": "success",
"link": {
"id": "link_123",
"name": "April landing page",
"token": "abcdef1234567890abcdef1234567890",
"url": "https://app.meingpt.com/auth?sponsored=abcdef1234567890abcdef1234567890",
"isActive": true,
"hasPassword": true,
"createdAt": "2026-04-16T10:15:00.000Z",
"completedRedemptionsCount": 0
}
}Error codes
400- Invalid request body401- Invalid or missing API key403- Feature not enabled or no access to the API404- Resource not found
Update a link
PATCH /api/sponsorship/v1/links/:linkIdUpdates the name and active state of an existing sponsorship link.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
name | String | No | New display name, 1 to 200 characters |
isActive | Boolean | No | Enables or disables the link |
Response
{
"status": "success",
"link": {
"id": "link_123",
"name": "Website header",
"token": "abcdef1234567890abcdef1234567890",
"url": "https://app.meingpt.com/auth?sponsored=abcdef1234567890abcdef1234567890",
"isActive": false,
"hasPassword": true,
"createdAt": "2026-04-16T10:15:00.000Z",
"completedRedemptionsCount": 7
}
}Error codes
400- Invalid request body401- Invalid or missing API key403- Feature not enabled or no access to the API404- Resource not found
Set or clear a link password
PATCH /api/sponsorship/v1/links/:linkId/passwordSets a password for a link or removes it again.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
password | String or null | Yes | New password with at least 4 characters, or null to remove the password |
Response
{
"status": "success",
"success": true
}Error codes
400- Invalid request body401- Invalid or missing API key403- Feature not enabled or no access to the API404- Resource not found
List campaign redemptions
GET /api/sponsorship/v1/campaigns/:campaignId/redemptions?page=1&pageSize=100&billingStatus=UNBILLED|BILLED|DISPUTED|WAIVEDLists completed redemptions for a campaign including billing metadata.
Request fields
| Field | Location | Type | Required | Description |
|---|---|---|---|---|
campaignId | Path | String | Yes | Campaign ID |
page | Query | Integer | No | Page number, default 1 |
pageSize | Query | Integer | No | Items per page, default 100, maximum 100 |
billingStatus | Query | String | No | Optional filter: UNBILLED, BILLED, DISPUTED, or WAIVED |
Response
{
"status": "success",
"redemptions": [
{
"id": "red_123",
"redeemedAt": "2026-04-12T15:20:00.000Z",
"sponsoredUntil": "2026-08-12T15:20:00.000Z",
"extendedUntil": "2026-09-30T23:59:59.000Z",
"extensionReason": "Partner extends pilot phase",
"includedSeats": 5,
"pricing": {
"model": "FIXED",
"amountEur": 5,
"unit": "PER_REDEMPTION"
},
"billingStatus": "UNBILLED",
"billingAmount": 99,
"billedAt": null,
"billingBatchId": null,
"organizationName": "Example GmbH",
"userEmail": "admin@example.com",
"linkName": "April landing page"
}
],
"total": 1,
"page": 1,
"pageSize": 100,
"totalPages": 1
}Error codes
400- Invalid query parameters401- Invalid or missing API key403- Feature not enabled or no access to the API404- Resource not found
Extending a sponsorship
PATCH /api/sponsorship/v1/redemptions/:redemptionId/extendExtends an existing redemption to a later end date.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
newSponsoredUntil | String (Date-Time) | Yes | New end date, must be later than the current sponsoredUntil |
reason | String | No | Optional internal reason for the extension |
Response
{
"status": "success",
"redemption": {
"id": "red_123",
"redeemedAt": "2026-04-12T15:20:00.000Z",
"sponsoredUntil": "2026-09-30T23:59:59.000Z",
"extendedUntil": "2026-09-30T23:59:59.000Z",
"extensionReason": "Partner extends pilot phase",
"campaignId": "camp_123",
"campaignName": "Pilot Campaign Q3",
"billingStatus": "UNBILLED",
"billingAmount": 99,
"billedAt": null,
"billingBatchId": null,
"includedSeats": 5,
"organizationName": "Example GmbH",
"userEmail": "admin@example.com",
"linkName": "April landing page",
"linkToken": "lnk_public_token",
"pricing": {
"model": "FIXED",
"amountEur": 5,
"unit": "PER_REDEMPTION"
}
}
}Error codes
400- Invalid request body or the new date is not later than the current end date401- Invalid or missing API key403- Feature not enabled or no access to the API404- Resource not found
Update redemption billing status
PATCH /api/sponsorship/v1/redemptions/:redemptionId/billingUpdates partner-side billing metadata for a completed redemption.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
billingStatus | String | Yes | New status: UNBILLED, BILLED, DISPUTED, or WAIVED |
billingAmount | Number | No | Optional amount, minimum 0 |
billingBatchId | String | No | Optional batch or invoice reference |
Response
{
"status": "success",
"success": true
}Error codes
400- Invalid request body401- Invalid or missing API key403- Feature not enabled or no access to the API404- Resource not found
Redemption URL flow
The partner first creates a sponsorship link. The API already returns the full URL in the url field, which is ${ORIGIN}/auth?sponsored=${token}.
When an end user opens that URL, they enter the normal authentication flow at /auth?sponsored=<token>. After successful sign-up or sign-in, a new sponsored organization is provisioned for that user with the duration configured on the campaign.
Pricing is read-only via the API. If meinGPT platform support has configured commercial terms, they appear in the pricing field; partners cannot change those values through the API.