openapi: 3.1.0
info:
  title: Adapty Web API
  version: 1.0.0
  description: |
    L'API Web Adapty vous permet d'intégrer la plateforme de gestion des abonnements 
    Adapty dans vos applications web. Cette API fournit des endpoints pour récupérer des paywalls, 
    enregistrer des vues de paywall et ajouter des données d'attribution.
servers:
  - url: https://api.adapty.io
    description: Serveur de production
paths:
  /api/v2/web-api/paywall/:
    post:
      summary: Obtenir un paywall
      description: Récupère le paywall depuis le placement fourni.
      operationId: getPaywall
      security:
        - apikeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GetPaywallRequest'
            examples:
              basic:
                summary: Requête de paywall simple
                value:
                  store: "app_store"
                  locale: "en"
                  placement_id: "PaywallPlacementId"
                  customer_user_id: "user123"
      responses:
        '200':
          description: La réponse en cas de succès contiendra l'objet Paywall.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaywallResponse'
              examples:
                basic:
                  summary: Réponse de paywall simple
                  value:
                    placement_id: "onboarding"
                    variation_id: "d76feea0-c0cf-4942-bef5-84ed701fc6db"
                    paywall_id: "9a93fe6f-9162-4dc0-b4b7-73079ed95c34"
                    ab_test_name: "1 week + 1 month | apple picture"
                    paywall_name: "1 week + 1 month | apple picture"
                    products:
                      - title: "1 week"
                        is_consumable: false
                        adapty_product_id: "1c3e03e1-9c43-4f94-aeb5-c7ae2f73d0c2"
                        vendor_product_id: "1_week_apple"
                        introductory_offer_eligibility: true
                        promotional_offer_eligibility: true
                        base_plan_id: null
                        offer: null
                      - title: "1 month"
                        is_consumable: false
                        adapty_product_id: "f4088450-45a8-4737-8db0-367e642d7dcb"
                        vendor_product_id: "1_month_apple"
                        introductory_offer_eligibility: true
                        promotional_offer_eligibility: true
                        base_plan_id: null
                        offer: null
                    remote_config:
                      lang: "en"
                      data: "{\"default_product_number\":1,\"features\":[\"#fresh\",\"#green\",\"#healthy1\"],\"soft_paywall\":false,\"image_url\":\"https://adapty.io/apple.png\"}"
        '400':
          description: Requête incorrecte
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParseError'
        '401':
          description: Non autorisé
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '404':
          description: Introuvable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VariationIdNotFoundError'

  /api/v2/web-api/paywall/visit/:
    post:
      summary: Enregistrer une vue de paywall
      description: |
        Adapty peut vous aider à mesurer le taux de conversion de vos paywalls. Cependant, 
        pour ce faire, vous devez enregistrer chaque affichage d'un paywall — sans cela, nous ne 
        connaîtrions que les utilisateurs ayant effectué un achat et nous manquerions ceux qui ne l'ont pas fait. 
        Utilisez cette requête pour enregistrer une vue de paywall.
      operationId: recordPaywallView
      security:
        - apikeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecordPaywallViewRequest'
            examples:
              basic:
                summary: Enregistrement simple d'une vue de paywall
                value:
                  visited_at: "2024-08-24T14:15:22Z"
                  store: "app_store"
                  variation_id: "00000000-0000-0000-0000-000000000000"
                  customer_user_id: "user123"
      responses:
        '201':
          description: La vue du paywall a été enregistrée avec succès.
          content:
            application/json:
              schema:
                type: object
                description: Corps de réponse vide
        '400':
          description: Requête incorrecte
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidDateFormatError'
        '401':
          description: Non autorisé
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '404':
          description: Introuvable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProfileNotFoundError'

  /api/v2/web-api/attribution/:
    post:
      summary: Ajouter une attribution personnalisée
      description: Ajoute des données d'attribution marketing personnalisées à un profil.
      operationId: addAttribution
      security:
        - apikeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddAttributionRequest'
            examples:
              basic:
                summary: Données d'attribution simples
                value:
                  status: "organic"
                  attribution_user_id: "attribution_user_id_value"
                  channel: "marketing_channel_value"
                  campaign: "campaign_name_value"
                  ad_group: "ad_group_name_value"
                  ad_set: "ad_set_name_value"
                  creative: "creative_name_value"
                  customer_user_id: "user123"
      responses:
        '201':
          description: L'attribution a été ajoutée avec succès au profil. Le corps de la réponse est vide.
          content:
            application/json:
              schema:
                type: object
                description: Corps de réponse vide
        '400':
          description: Requête incorrecte
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidEnumerationMemberError'
        '401':
          description: Non autorisé
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '404':
          description: Introuvable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProfileNotFoundError'

components:
  securitySchemes:
    apikeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: |
        Les requêtes API doivent être authentifiées avec votre clé API publique dans l'en-tête **Authorization** 
        avec la valeur `Api-Key {votre_clé_api_publique}`, par exemple 
        `Api-Key public_live_...`. Vous trouverez cette clé dans l'Adapty Dashboard -> 
        **App Settings** -> onglet **General** -> section **API keys**.

  schemas:
    GetPaywallRequest:
      type: object
      required:
        - store
        - placement_id
      properties:
        store:
          type: string
          description: |
            Store où le produit a été acheté. Valeurs possibles : `app_store`, `play_store`, `stripe`, ou le `Store ID` de votre store personnalisé.
          example: "app_store"
        locale:
          type: string
          description: Identifiant de la locale du paywall. Ce paramètre doit être un code de langue composé d'un ou plusieurs sous-tags séparés par le caractère « - ». Le premier sous-tag correspond à la langue, le second à la région.
          example: "en"
        placement_id:
          type: string
          description: L'identifiant du placement. Il s'agit de la valeur que vous avez spécifiée lors de la création d'un placement dans votre Adapty Dashboard.
          example: "PaywallPlacementId"
        customer_user_id:
          type: string
          description: Soit `customer_user_id`, soit `profile_id` est requis. L'identifiant utilisateur que vous utilisez dans votre application pour identifier l'utilisateur, le cas échéant. Il peut s'agir par exemple de l'UUID, de l'e-mail ou de tout autre identifiant de l'utilisateur.
          example: "user123"
        profile_id:
          type: string
          description: Soit `customer_user_id`, soit `profile_id` est requis. Identifiant d'un utilisateur dans Adapty.
          example: "3286abd3-48b0-4e9c-a5f6-ac0a006804a6"

    RecordPaywallViewRequest:
      type: object
      required:
        - store
        - variation_id
      properties:
        customer_user_id:
          type: string
          description: Identifiant d'un utilisateur dans votre système. Soit `customer_user_id`, soit `profile_id` est requis.
          example: "user123"
        profile_id:
          type: string
          description: Identifiant d'un utilisateur dans Adapty. Soit `customer_user_id`, soit `profile_id` est requis.
          example: "3286abd3-48b0-4e9c-a5f6-ac0a006804a6"
        visited_at:
          type: string
          format: date-time
          description: La date et l'heure auxquelles l'utilisateur a ouvert le paywall.
          example: "2024-08-24T14:15:22Z"
        store:
          type: string
          description: |
            Store où le produit a été acheté. Valeurs possibles : `app_store`, `play_store`, `stripe`, ou le `Store ID` de votre store personnalisé.
          example: "app_store"
        variation_id:
          type: string
          format: uuid
          description: L'ID de variante utilisé pour associer les achats au paywall spécifique depuis lequel ils ont été effectués.
          example: "00000000-0000-0000-0000-000000000000"

    AddAttributionRequest:
      type: object
      required:
        - status
      properties:
        status:
          type: string
          enum: [organic, non_organic, unknown]
          description: Indique si l'attribution est organique ou non organique.
          example: "organic"
        attribution_user_id:
          type: string
          description: Identifiant attribué à l'utilisateur par la source d'attribution.
          example: "attribution_user_id_value"
        channel:
          type: string
          description: Nom du canal marketing.
          example: "marketing_channel_value"
        campaign:
          type: string
          description: Nom de la campagne marketing.
          example: "campaign_name_value"
        ad_group:
          type: string
          description: Groupe d'annonces de l'attribution.
          example: "ad_group_name_value"
        ad_set:
          type: string
          description: Ensemble d'annonces de l'attribution.
          example: "ad_set_name_value"
        creative:
          type: string
          description: Mot-clé créatif de l'attribution.
          example: "creative_name_value"
        customer_user_id:
          type: string
          description: Identifiant utilisateur que vous utilisez dans votre application pour identifier l'utilisateur, le cas échéant. Il peut s'agir par exemple de l'UUID, de l'e-mail ou de tout autre identifiant de l'utilisateur. Null si vous ne l'avez pas défini. Soit `customer_user_id`, soit `profile_id` est requis.
          example: "user123"
        profile_id:
          type: string
          description: Identifiant d'un utilisateur dans Adapty. Vous pouvez le trouver dans le champ **Adapty ID** du profil dans l'Adapty Dashboard. Soit `customer_user_id`, soit `profile_id` est requis.
          example: "3286abd3-48b0-4e9c-a5f6-ac0a006804a6"

    PaywallResponse:
      type: object
      required:
        - placement_id
        - variation_id
        - paywall_id
        - paywall_name
        - products
      properties:
        placement_id:
          type: string
          description: L'ID du placement où ce paywall est affiché. Cette valeur est définie lors de la création d'un placement dans votre Adapty Dashboard.
          example: "onboarding"
        variation_id:
          type: string
          format: uuid
          description: L'ID de variante utilisé pour suivre les achats liés à ce paywall spécifique.
          example: "d76feea0-c0cf-4942-bef5-84ed701fc6db"
        paywall_id:
          type: string
          format: uuid
          description: L'identifiant unique du paywall.
          example: "9a93fe6f-9162-4dc0-b4b7-73079ed95c34"
        ab_test_name:
          type: string
          description: Le nom du test A/B parent.
          example: "1 week + 1 month | apple picture"
        paywall_name:
          type: string
          description: Le nom du paywall, tel que défini dans votre Adapty Dashboard.
          example: "1 week + 1 month | apple picture"
        products:
          type: array
          items:
            $ref: '#/components/schemas/Product'
          description: Tableau d'objets Product contenant les informations sur les produits du paywall.
        remote_config:
          $ref: '#/components/schemas/RemoteConfig'
          description: Un objet RemoteConfig contenant la configuration Remote Config complète du paywall.

    Product:
      type: object
      required:
        - is_consumable
        - vendor_product_id
      properties:
        title:
          type: string
          description: Nom du produit issu de la section Produits dans l'Adapty Dashboard.
        is_consumable:
          type: boolean
          description: Indique si le produit est consommable.
        adapty_product_id:
          type: string
          format: uuid
          description: Identifiant interne du produit tel qu'utilisé dans Adapty.
        vendor_product_id:
          type: string
          description: L'identifiant du produit dans les stores.
        introductory_offer_eligibility:
          type: boolean
          description: Indique si l'utilisateur est éligible à une offre de lancement iOS.
        promotional_offer_eligibility:
          type: boolean
          description: Indique si l'utilisateur est éligible à une offre promotionnelle.
        base_plan_id:
          type: string
          nullable: true
          description: |
            ID du plan de base pour Google Play ou ID de prix pour Stripe. 
            Voir [Base plan ID](https://support.google.com/googleplay/android-developer/answer/12154973) pour Google Play ou 
            [price ID](https://docs.stripe.com/products-prices/how-products-and-prices-work#use-products-and-prices) pour Stripe.
        offer:
          allOf:
            - $ref: '#/components/schemas/Offer'
          nullable: true
          description: Un objet Offer au format JSON.

    Offer:
      type: object
      required:
        - category
        - type
      properties:
        category:
          type: string
          enum: [introductory, promotional, offer_code, win_back]
          description: La catégorie de l'offre appliquée.
        type:
          type: string
          enum: [free_trial, pay_as_you_go, pay_up_front, unknown]
          description: Le type d'offre active. Si cette valeur n'est pas null, cela signifie que l'offre a été appliquée durant la période d'abonnement en cours.
        id:
          type: string
          nullable: true
          description: L'identifiant de l'offre appliquée.

    RemoteConfig:
      type: object
      required:
        - lang
        - data
      properties:
        lang:
          type: string
          description: |
            Code de locale pour la localisation du paywall. Il utilise des sous-tags de langue et de région 
            séparés par un tiret (-). Exemples : `en` pour l'anglais, `pt-br` pour le portugais brésilien.
          example: "en"
        data:
          type: string
          description: |
            Chaîne JSON sérialisée représentant le Remote Config de votre paywall. 
            Vous pouvez la trouver dans l'onglet Remote Config d'un paywall spécifique dans l'Adapty Dashboard.

    ParseError:
      type: object
      properties:
        errors:
          type: array
          items:
            type: object
            properties:
              source:
                type: string
              errors:
                type: array
                items:
                  type: string
        error_code:
          type: string
        status_code:
          type: integer

    UnauthorizedError:
      type: object
      properties:
        errors:
          type: array
          items:
            type: object
            properties:
              source:
                type: string
              errors:
                type: array
                items:
                  type: string
        error_code:
          type: string
        status_code:
          type: integer

    VariationIdNotFoundError:
      type: object
      properties:
        errors:
          type: array
          items:
            type: object
            properties:
              source:
                type: string
              errors:
                type: array
                items:
                  type: string
        error_code:
          type: string
        status_code:
          type: integer

    InvalidDateFormatError:
      type: object
      properties:
        errors:
          type: array
          items:
            type: object
            properties:
              source:
                type: string
              errors:
                type: array
                items:
                  type: string
        error_code:
          type: string
        status_code:
          type: integer

    InvalidEnumerationMemberError:
      type: object
      properties:
        errors:
          type: array
          items:
            type: object
            properties:
              source:
                type: string
              errors:
                type: array
                items:
                  type: string
        error_code:
          type: string
        status_code:
          type: integer

    ProfileNotFoundError:
      type: object
      properties:
        errors:
          type: array
          items:
            type: object
            properties:
              source:
                type: string
              errors:
                type: array
                items:
                  type: string
        error_code:
          type: string
        status_code:
          type: integer

security:
  - apikeyAuth: []