Skip to content
Developer docs
⌘ K
Dashboard ↗

HTTP endpoints

upsertPartner

POST /api/v1/partners

Requires partners:write. Keep the Bearer key on your server.

The HTTP response is the partner itself, with status 201 when created or 200 when updated. The SDK returns { partner, created }. Setting stripeAccountId also requires payouts:write.

SDK

ts
grizzlee.upsertPartner(input: { email: string; name: string; externalId: string; customerIds?: string[] | undefined; programIds?: string[] | undefined; addProgramIds?: string[] | undefined; removeProgramIds?: string[] | undefined; labels?: string[] | undefined; properties?: Record<string, string | number | boolean> | undefined; stripeAccountId?: string | null | undefined; locale?: "en" | "fr-CA" | "hy" | "ru" | null | undefined; } & PartnerSignalsInput): Promise<PartnerUpsertResult>

HTTP

Use your backend's HTTP client. The cURL request shows the wire format. Replace path parameters and example values.

sh
curl --fail-with-body --request POST \
  'https://app.grizzlee.ca/api/v1/partners' \
  -H "Authorization: Bearer $GRIZZLEE_SERVER_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"externalId":"merchant-partner-001","customerIds":["customer-example"],"name":"Example referral program","email":"partner@example.com"}'

Request body

FieldTypeRequiredDetails
externalIdstringYes
customerIdsarrayNo
namestringYes
emailstringYesemail
programIdsarrayNo
addProgramIdsarrayNo
removeProgramIdsarrayNo
labelsarrayNo
propertiesobjectNo
stripeAccountIdunionNo
localeunionNo
signalsobjectNo

stripeAccountId

Variant 1

Type: string.

Variant 2

Type: null.

locale

Variant 1

Type: string.

Variant 2

Type: null.

signals

FieldTypeRequiredDetails
signals.emailstringNo
signals.phonestringNo
signals.phoneHashstringNo
signals.paymentFingerprintstringNo
signals.deviceIdstringNo
signals.ipAddressstringNo

Request schema

json
{
  "type": "object",
  "properties": {
    "externalId": {
      "type": "string",
      "minLength": 1,
      "maxLength": 120
    },
    "customerIds": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 120
      },
      "maxItems": 100
    },
    "name": {
      "type": "string",
      "minLength": 2,
      "maxLength": 100
    },
    "email": {
      "type": "string",
      "format": "email",
      "maxLength": 254
    },
    "programIds": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 120
      },
      "maxItems": 100
    },
    "addProgramIds": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 120
      },
      "maxItems": 100
    },
    "removeProgramIds": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 120
      },
      "maxItems": 100
    },
    "labels": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 60
      },
      "maxItems": 10
    },
    "properties": {
      "type": "object",
      "additionalProperties": {
        "anyOf": [
          {
            "type": "string",
            "maxLength": 500
          },
          {
            "type": "number",
            "minimum": -1000000000000,
            "maximum": 1000000000000
          },
          {
            "type": "boolean"
          }
        ]
      }
    },
    "stripeAccountId": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 255,
          "pattern": "^acct_[A-Za-z0-9]+$"
        },
        {
          "type": "null"
        }
      ]
    },
    "locale": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "en",
            "fr-CA",
            "hy",
            "ru"
          ]
        },
        {
          "type": "null"
        }
      ]
    },
    "signals": {
      "type": "object",
      "properties": {
        "email": {
          "type": "string",
          "maxLength": 254
        },
        "phone": {
          "type": "string",
          "maxLength": 40
        },
        "phoneHash": {
          "type": "string",
          "pattern": "^[0-9a-fA-F]{64}$"
        },
        "paymentFingerprint": {
          "type": "string",
          "minLength": 1,
          "maxLength": 255
        },
        "deviceId": {
          "type": "string",
          "minLength": 1,
          "maxLength": 255
        },
        "ipAddress": {
          "type": "string",
          "maxLength": 64
        }
      },
      "additionalProperties": false
    }
  },
  "required": [
    "externalId",
    "name",
    "email"
  ],
  "additionalProperties": false
}

Response

HTTP responses wrap this value in data. The SDK returns the value directly unless the note above describes a wrapper.

FieldTypeRequiredDetails
programIdsarrayYes
idstringYes
companyIdstringYes
referralCodestringYes
aliasstringYesThe partner's short code, such as KARL7Q. Unique in the company and accepted wherever referralCode is, in any case. It never changes after creation, except that erasure replaces it with the uppercase referralCode.
activebooleanYes
createdAtstringYes
erasedAtstringNoWhen the merchant erased the partner's personal data. An erased partner is named ERASED_PARTNER_NAME, has an empty email and no customer links, labels or properties. It stays inactive and its external ID cannot be registered again.
emailstringYes
namestringYes
externalIdstringYes
customerIdsarrayNoMerchant customer IDs belonging to this partner. Supplied lists replace the links.
labelsarrayNo
propertiesobjectNo
stripeAccountIdunionNoThe partner's Stripe connected account on the merchant's Stripe platform. Scheduled payouts send Stripe transfers here when the payout schedule names a Stripe connection. Setting it needs payouts:write. Null removes it.
localeunionNoThe partner's language: en, fr-CA, hy or ru. Emails, the embedded dashboard and the partner portal use it when the company uses it, and the company's default otherwise. Null removes it.

properties

Type: object.

stripeAccountId

Variant 1

Type: null.

Variant 2

Type: string.

locale

Variant 1

Type: null.

Variant 2

Type: string.

Variant 3

Type: string.

Variant 4

Type: string.

Variant 5

Type: string.

Response schema

json
{
  "type": "object",
  "properties": {
    "programIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "id": {
      "type": "string"
    },
    "companyId": {
      "type": "string"
    },
    "referralCode": {
      "type": "string"
    },
    "alias": {
      "type": "string",
      "description": "The partner's short code, such as KARL7Q. Unique in the company and accepted wherever\nreferralCode is, in any case. It never changes after creation, except that erasure replaces it\nwith the uppercase referralCode."
    },
    "active": {
      "type": "boolean"
    },
    "createdAt": {
      "type": "string"
    },
    "erasedAt": {
      "type": "string",
      "description": "When the merchant erased the partner's personal data. An erased partner is named\nERASED_PARTNER_NAME, has an empty email and no customer links, labels or properties. It stays\ninactive and its external ID cannot be registered again."
    },
    "email": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "externalId": {
      "type": "string"
    },
    "customerIds": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Merchant customer IDs belonging to this partner. Supplied lists replace the links."
    },
    "labels": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "properties": {
      "type": "object",
      "properties": {},
      "additionalProperties": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "number"
          },
          {
            "type": "boolean",
            "const": false
          },
          {
            "type": "boolean",
            "const": true
          }
        ]
      }
    },
    "stripeAccountId": {
      "anyOf": [
        {
          "type": "null"
        },
        {
          "type": "string"
        }
      ],
      "description": "The partner's Stripe connected account on the merchant's Stripe platform. Scheduled payouts\nsend Stripe transfers here when the payout schedule names a Stripe connection. Setting it\nneeds payouts:write. Null removes it."
    },
    "locale": {
      "anyOf": [
        {
          "type": "null"
        },
        {
          "type": "string",
          "const": "en"
        },
        {
          "type": "string",
          "const": "fr-CA"
        },
        {
          "type": "string",
          "const": "hy"
        },
        {
          "type": "string",
          "const": "ru"
        }
      ],
      "description": "The partner's language: en, fr-CA, hy or ru. Emails, the embedded dashboard and the partner\nportal use it when the company uses it, and the company's default otherwise. Null\nremoves it."
    }
  },
  "required": [
    "programIds",
    "id",
    "companyId",
    "referralCode",
    "alias",
    "active",
    "createdAt",
    "email",
    "name",
    "externalId"
  ]
}

Errors

Failures return { "error": { "code": "...", "message": "...", "details": {} } }. Details are optional. See error statuses. Reuse an unchanged event payload when retrying.