> ## Documentation Index
> Fetch the complete documentation index at: https://docs.promostack.app/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /referrer

> Get or create a referrer and fetch their progress

# Get or Create Referrer

This unified endpoint performs two actions:

1. **Get or Create**: Checks if a referrer exists for the given `uid`. If not, creates a new one.
2. **Fetch Progress**: Returns the referrer's current stats, rewards earned, and progress toward the next reward.

Use this endpoint when a user opens the referral section of your app.

## Request

<ParamField body="uid" type="string" required>
  Unique identifier for the user in your app (e.g., user ID, RevenueCat app\_user\_id)
</ParamField>

<ParamField body="metadata" type="object">
  Optional metadata about the referrer (e.g., display name, avatar URL). Only used when creating a new referrer.
</ParamField>

### Example Request

```bash theme={null}
curl -X POST https://api.promostack.app/referrer \
  -H "x-api-key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "uid": "user_123",
    "metadata": {
      "name": "John Doe"
    }
  }'
```

## Response

<ResponseField name="referrer_id" type="string">
  Unique identifier for the referrer
</ResponseField>

<ResponseField name="referral_link" type="string">
  Full URL to the referral landing page
</ResponseField>

<ResponseField name="referrer_slug" type="string">
  Unique slug for the referrer (part of the URL)
</ResponseField>

<ResponseField name="metacode" type="string">
  The metacode that referees will enter in the app (same as referrer\_slug)
</ResponseField>

<ResponseField name="status" type="string">
  Referrer status: `active`, `paused`, or `ended`
</ResponseField>

<ResponseField name="stats" type="object">
  General statistics

  <Expandable title="properties">
    <ResponseField name="referrals_count" type="number">
      Total number of confirmed referrals
    </ResponseField>

    <ResponseField name="rewards_earned" type="number">
      Total number of rewards earned
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="progress" type="object">
  Platform-specific progress details

  <Expandable title="properties">
    <ResponseField name="ios" type="object">
      iOS platform progress

      <Expandable title="properties">
        <ResponseField name="current" type="number">Current referrals</ResponseField>
        <ResponseField name="threshold" type="number">Target for next reward</ResponseField>
        <ResponseField name="next_reward_at" type="number">Total count for next reward</ResponseField>
        <ResponseField name="percentage" type="number">Progress (0-100)</ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="android" type="object">
      Android platform progress (same structure as iOS)
    </ResponseField>
  </Expandable>
</ResponseField>

### Example Response

```json theme={null}
{
  "referrer_id": "550e8400-e29b-41d4-a716-446655440000",
  "referral_link": "https://promostack.app/r/abc123",
  "referrer_slug": "abc123",
  "metacode": "abc123",
  "status": "active",
  "stats": {
    "referrals_count": 3,
    "rewards_earned": 0
  },
  "progress": {
    "ios": {
      "current": 3,
      "threshold": 5,
      "next_reward_at": 5,
      "percentage": 60
    },
    "android": {
      "current": 0,
      "threshold": 5,
      "next_reward_at": 5,
      "percentage": 0
    }
  }
}
```

## Usage in Mobile App

<CodeGroup>
  ```swift iOS theme={null}
  struct ReferrerResponse: Codable {
      let referrer_id: String
      let referral_link: String
      let metacode: String
      let stats: Stats
      let progress: Progress
  }

  func getReferrer(userId: String) async throws -> ReferrerResponse {
      let url = URL(string: "https://api.promostack.app/referrer")!
      var request = URLRequest(url: url)
      request.httpMethod = "POST"
      request.setValue(apiKey, forHTTPHeaderField: "x-api-key")
      request.setValue("application/json", forHTTPHeaderField: "Content-Type")
      
      let body = ["uid": userId]
      request.httpBody = try JSONEncoder().encode(body)
      
      let (data, _) = try await URLSession.shared.data(for: request)
      return try JSONDecoder().decode(ReferrerResponse.self, from: data)
  }
  ```

  ```kotlin Android theme={null}
  suspend fun getReferrer(userId: String): ReferrerResponse {
      val client = OkHttpClient()
      val json = JSONObject().put("uid", userId)
      
      val request = Request.Builder()
          .url("https://api.promostack.app/referrer")
          .post(json.toString().toRequestBody("application/json".toMediaType()))
          .addHeader("x-api-key", apiKey)
          .build()
      
      val response = client.newCall(request).execute()
      return Gson().fromJson(response.body?.string(), ReferrerResponse::class.java)
  }
  ```
</CodeGroup>

## Error Responses

<ResponseExample>
  ```json 400 Bad Request theme={null}
  {
    "error": {
      "code": "VALIDATION_ERROR",
      "message": "Missing required field: uid"
    }
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "error": {
      "code": "UNAUTHORIZED",
      "message": "Invalid or missing API key"
    }
  }
  ```
</ResponseExample>
