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

# Construire avec les SDK Metronome

Metronome fournit des kits de développement logiciel (SDK) puissants conçus pour intégrer en toute transparence les API de facturation Metronome dans vos applications. Les SDK pour Python, Go, Ruby et Node.js offrent aux développeurs des options flexibles pour mettre en œuvre les fonctionnalités de Metronome sur différentes plateformes et environnements.

Cette page présente un système de facturation à l'usage simple mais puissant en Python, Node, Ruby ou Golang :

1. Installez et configurez le SDK Metronome.
2. Envoyez des événements d'utilisation à Metronome, posant les bases de la facturation à la consommation.
3. Créez un billable metric pour définir comment Metronome doit agréger et mesurer l'utilisation.
4. Créez un client dans le système et associez-le à des événements d'utilisation.
5. Configurez la tarification et le packaging de votre produit.
6. Créez un contrat pour le client, permettant la génération automatique de factures en fonction de son utilisation.

## Fonctionnalités des SDK

Chaque dépôt GitHub de SDK contient une documentation détaillée, des exemples et des ressources pour vous aider à tirer le meilleur parti de Metronome dans vos applications :

* [SDK Python](https://github.com/Metronome-Industries/metronome-python/blob/main/README.md)
* [SDK Go](https://github.com/Metronome-Industries/metronome-go/blob/main/README.md)
* [SDK Ruby](https://github.com/Metronome-Industries/metronome-ruby/blob/main/README.md)
* [SDK Node.js](https://github.com/Metronome-Industries/metronome-node/blob/main/README.md)

Les principales fonctionnalités des SDK incluent :

* **Typage fort des endpoints et objets Metronome** qui améliore la productivité du développeur grâce à une meilleure auto-complétion et au support IDE pour les objets Metronome.
* **Prise en charge de la pagination** qui simplifie la récupération et la gestion des données paginées depuis les services Metronome.
* **Prise en charge automatique des nouvelles tentatives** : par défaut, chaque requête est retentée jusqu'à trois fois en cas d'échec. Vous pouvez le configurer pour n'importe quel nombre de tentatives. Utilisez ceci pour gérer automatiquement les erreurs transitoires et les problèmes réseau sans avoir à implémenter de logique de nouvelle tentative.

Bien que ce guide couvre les fondamentaux, Metronome offre bien plus de fonctionnalités pour modéliser différents modèles métier. Consultez le dépôt du SDK pour voir ce qu'il est possible de faire.

## 1. Installer et configurer le SDK

Installez et configurez d'abord le SDK dans votre environnement :

<CodeGroup>
  ```bash Python theme={null}
  pip install --pre metronome-sdk
  ```

  ```bash Node theme={null}
  npm install @metronome/sdk
  ```

  ```bash Ruby theme={null}
  gem install metronome-sdk
  ```

  ```bash Go theme={null}
  go get -u 'github.com/Metronome-Industries/metronome-go'
  ```
</CodeGroup>

Ensuite, configurez le SDK en transmettant une [clé d'API](/fr/api-reference/authentication) valide comme jeton bearer d'autorisation. Par défaut, le SDK recherche la clé d'API dans la variable d'environnement `METRONOME_BEARER_TOKEN`. Dans cet exemple, elle sera transmise comme argument au constructeur à la place.

<CodeGroup>
  ```python Python theme={null}
  from metronome import Metronome

  client = Metronome(
    # Defaults to os.environ.get("METRONOME_BEARER_TOKEN") if omitted
    bearer_token="My bearer token",
  )
  ```

  ```javascript Node theme={null}
  import Metronome from '@metronome/sdk'

  const client = new Metronome({
    // Defaults to os.environ.get("METRONOME_BEARER_TOKEN") if omitted
    bearerToken: "My bearer token",
  });
  ```

  ```ruby Ruby theme={null}
  require "bundler/setup"
  require "metronome_sdk"

  metronome = MetronomeSDK::Client.new(
      bearer_token: "My Bearer Token" # defaults to ENV["METRONOME_BEARER_TOKEN"]
  )
  ```

  ```go Go theme={null}
  package main

  import (
    "context"
    "github.com/Metronome-Industries/metronome-go"
    "github.com/Metronome-Industries/metronome-go/option"
  )

  func main() {
    client := metronome.NewClient(
      option.WithBearerToken("My bearer token"), // defaults to os.LookupEnv("METRONOME_BEARER_TOKEN") if omitted
    )
  }
  ```
</CodeGroup>

## 2. Envoyer des événements d'utilisation

Le modèle de facturation à l'usage s'appuie sur les données d'utilisation capturées auprès des utilisateurs de votre plateforme. Metronome accepte les charges utiles d'utilisation dans tous les formats via l'endpoint [/ingest](/fr/api-reference/usage/ingest-events).

Utilisez le SDK pour envoyer des données à Metronome :

<CodeGroup>
  ```python Python theme={null}
  response = client.v1.usage.ingest(
    usage=[
      {
        "transaction_id": "9995a70e-a2c5-4904-b96d-70de446f420e",
        "timestamp": "2024-08-01T00:00:00Z",
        "customer_id": "team@example.com",
        "event_type": "language_model",
        "properties": {
          "model": "langModel4",
          "user_id": "johndoe",
          "tokens": 1000000
        }
      }
    ]
  )
  ```

  ```javascript Node theme={null}
  async function main() {
    await client.v1.usage.ingest({
      usage: [{
        transaction_id: '9995a70e-a2c5-4904-b96d-70de446f420e',
        timestamp: "2024-08-01T00:00:00.000Z",
        customer_id: 'team@example.com',
        event_type: 'language_model',
        properties: {
          model: "langModel4",
          user_id: "johndoe",
          tokens: 1000000
        }
      }],
    });
  }

  main();
  ```

  ```ruby Ruby theme={null}
  result = metronome.v1.usage.ingest(
      usage: [
        {
          transaction_id: '9995a70e-a2c5-4904-b96d-70de446f420e',
          timestamp: "2024-08-01T00:00:00.000Z",
          customer_id: 'team@example.com',
          event_type: 'language_model',
          properties: {
            model: "langModel4",
            user_id: "johndoe",
            tokens: 1000000
          }
        }
      ]
  )

  puts(result)
  ```

  ```go Go theme={null}
  err := client.V1.Usage.Ingest(context.TODO(), metronome.UsageIngestParams{
    Usage: []metronome.UsageIngestParamsUsage{{
      TransactionID: metronome.F("9995a70e-a2c5-4904-b96d-70de446f420e"),
      Timestamp:     metronome.F("2024-08-01T00:00:00Z"),
      CustomerID:    metronome.F("team@example.com"),
      EventType:     metronome.F("language_model"),
      Properties: metronome.F(map[string]interface{}{
        "model":   "langModel4",
        "user_id": "johndoe",
        "tokens":  1000000,
      }),
    }},
  })
  if err != nil {
    panic(err.Error())
  }
  ```
</CodeGroup>

Les propriétés utilisées dans cet exemple sont :

* `usage`, vous permet de transmettre plusieurs charges utiles d'événements dans une requête. Metronome prend en charge la transmission de jusqu'à 100 événements dans une seule requête.
* `transaction_id`, fournit à Metronome la clé d'idempotence unique pour l'événement. Metronome déduplique sur la base de cet ID, ce qui vous permet d'envoyer des événements potentiellement plusieurs fois sans risque de facturer deux fois vos clients.
* `timestamp`, l'heure à laquelle l'événement s'est produit. Envoyez des événements avec n'importe quel horodatage jusqu'à 34 jours dans le passé.
* `customer_id`, l'ID client dans Metronome ou tout autre identifiant client que vous souhaitez définir. Par exemple, l'e-mail du client ou l'ID client interne au sein de votre plateforme. Des étapes ultérieures montrent comment définir ces identifiants personnalisés pour vos clients dans Metronome.
* `event_type`, une chaîne arbitraire que vous pouvez définir dans la requête.
* `properties`, un ensemble arbitraire de données à inclure dans la charge utile pour la mesure et le groupement dans Metronome.

Le succès avec Metronome dépend des données que vous fournissez, il est donc important de bien concevoir les [événements d'utilisation](/fr/guides/events/design-usage-events).

Pour afficher tous les événements envoyés à Metronome, accédez à l'onglet **Events** dans l'[application Metronome](https://app.metronome.com/).

Pour l'événement envoyé dans l'exemple, il est entré avec succès dans le système Metronome. Cependant, il n'a pas encore été associé à un metric pour commencer la mesure ni à un client dans le système.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/TrrblT2KR7zYyGbN/images/api-reference/sdks/sdk-view-event-73e1747ae1551477facc43cbc57b5d41.png?fit=max&auto=format&n=TrrblT2KR7zYyGbN&q=85&s=1513cdfb83df0156e8bf66f653f10e02" alt="View an event" width="2172" height="732" data-path="images/api-reference/sdks/sdk-view-event-73e1747ae1551477facc43cbc57b5d41.png" />
</Frame>

## 3. Créer un billable metric

Un billable metric décrit une agrégation par client sur un sous-ensemble d'événements d'utilisation. En configurant un billable metric, vous indiquez à Metronome comment associer les événements d'utilisation aux produits que vous facturez.

Voici un exemple de configuration de billable metric qui correspond à l'événement d'utilisation envoyé dans l'exemple précédent :

<CodeGroup>
  ```python Python theme={null}
  response = client.v1.billable_metrics.create(
    name="langModel4",
    event_type_filter={
      "in_values": [
        "language_model"
      ]
    },
    property_filters=[
      {
        "name": "model",
        "exists": True,
        "in_values": [
          "langModel4"
        ]
      },
      {
        "name": "user_id",
        "exists": True
      },
      {
        "name": "tokens",
        "exists": True
      }
    ],
    aggregation_key="tokens",
    aggregation_type="SUM",
    group_keys=[
      ["user_id"]
    ]
  )

  billable_metric_id = response.data.id
  ```

  ```javascript Node theme={null}
  const billableMetricsResponse = await client.v1.billableMetrics.create({
    name: "langModel4",
    event_type_filter: {
      in_values: [
        "language_model"
      ]
    },
    property_filters: [
      {
        name: "model",
        exists: true,
        in_values: [
          "langModel4"
        ]
      },
      {
        name: "user_id",
        exists: true
      },
      {
        name: "tokens",
        exists: true,
      }
    ],
    aggregation_key: "tokens",
    aggregation_type: "SUM",
    group_keys: [
      ["user_id"]
    ]
  });

  const billableMetricId = billableMetricsResponse.data.id;
  ```

  ```ruby Ruby theme={null}
  response = client.v1.billable_metrics.create(
    name: "langModel4",
    event_type_filter: {
      in_values: [
        "language_model"
      ]
    },
    property_filters: [
      {
        name: "model",
        exists: true,
        in_values: [
          "langModel4"
        ]
      },
      {
        name: "user_id",
        exists: true
      },
      {
        name: "tokens",
        exists: true
      }
    ],
    aggregation_key: "tokens",
    aggregation_type: "SUM",
    group_keys: [
      ["user_id"]
    ]
  )

  billable_metric_id = response.data.id
  ```

  ```go Go theme={null}
  billableMetricResponse, err := client.V1.BillableMetrics.New(context.TODO(), metronome.BillableMetricNewParams{
    Name: metronome.F("langModel4"),
    EventTypeFilter: metronome.F(metronome.EventTypeFilterParam{
      InValues: metronome.F([]string{"language_model"}),
    }),
    PropertyFilters: metronome.F([]metronome.PropertyFilterParam{
      {
        Name:   metronome.F("model"),
        Exists: metronome.F(true),
        InValues: metronome.F([]string{
          "langModel4",
        }),
      },
      {
        Name:   metronome.F("user_id"),
        Exists: metronome.F(true),
      },
      {
        Name:   metronome.F("tokens"),
        Exists: metronome.F(true),
      },
    }),
    AggregationKey:  metronome.F("tokens"),
    AggregationType: metronome.F(metronome.BillableMetricNewParamsAggregationTypeSum),
  })

  if err != nil {
    panic(err.Error())
  }
  billableMetricID := billableMetricResponse.Data.ID
  ```
</CodeGroup>

Les propriétés utilisées dans le code incluent :

* `name`, le nom à donner à votre billable metric.
* `event_type_filter`, l'ensemble de valeurs comparées au champ `event_type` dans les événements d'utilisation. Omettez ceci si vous souhaitez correspondre à tous les types d'événements.
* `property_filters`, l'ensemble des propriétés que vous vous attendez à trouver dans la charge utile d'utilisation. Si vous marquez une propriété comme `exists=True` dans la définition du billable metric et que la propriété n'est pas trouvée dans la charge utile, le billable metric ne correspondra pas à l'événement.
* `aggregation_key`, utilisé pour définir la propriété avec la valeur pertinente sur laquelle agréger.
* `aggregation_type`, utilisé pour indiquer à Metronome comment agréger les valeurs spécifiées par la `aggregation_key` au fur et à mesure de leur arrivée dans le système. Les opérations prises en charge sont `SUM`, `COUNT` et `MAX`.
* `group_keys`, utilisé pour définir des propriétés permettant de séparer les données d'utilisation en différents groupes, similaire à une clause `group by` en SQL. L'exemple ci-dessus définit `user_id` comme clé de groupe, ce qui vous permet d'afficher la facture séparée selon la quantité de jetons consommée par chaque utilisateur.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/TrrblT2KR7zYyGbN/images/api-reference/sdks/sdk-billable-metric-548bf969fd6260246719c508d04edbbf.png?fit=max&auto=format&n=TrrblT2KR7zYyGbN&q=85&s=beaec32999ea48566c29221a15796773" alt="Billable metric" width="856" height="940" data-path="images/api-reference/sdks/sdk-billable-metric-548bf969fd6260246719c508d04edbbf.png" />
</Frame>

Notez que les billable metrics ne correspondent qu'aux événements d'utilisation envoyés après la création du billable metric. Maintenant que vous avez créé le metric, envoyez un autre événement d'utilisation pour vérifier qu'il correspond comme prévu :

<CodeGroup>
  ```python Python theme={null}
  response = client.v1.usage.ingest(
    usage=[
      {
        "transaction_id": "7e28f511-d66c-4517-91ef-a92c108e56de",
        "timestamp": "2024-08-01T00:00:00Z",
        "customer_id": "team@example.com",
        "event_type": "language_model",
        "properties": {
          "model": "langModel4",
          "user_id": "johndoe",
          "tokens": 1000000
        }
      }
    ]
  )
  ```

  ```javascript Node theme={null}
  await client.v1.usage.ingest({
    usage: [
      {
        transaction_id: '7e28f511-d66c-4517-91ef-a92c108e56de',
        timestamp: "2024-08-01T00:00:00.000Z",
        customer_id: 'team@example.com',
        event_type: 'language_model',
        properties: {
          model: "langModel4",
          user_id: "johndoe",
          tokens: 1000000
        }
      }
    ]
  });
  ```

  ```ruby Ruby theme={null}
  response = client.v1.usage.ingest(
    usage: [
      {
        transaction_id: "7e28f511-d66c-4517-91ef-a92c108e56de",
        timestamp: "2024-08-01T00:00:00Z",
        customer_id: "team@example.com",
        event_type: "language_model",
        properties: {
          model: "langModel4",
          user_id: "johndoe",
          tokens: 1000000
        }
      }
    ]
  )
  ```

  ```go Go theme={null}
  err := client.V1.Usage.Ingest(context.TODO(), metronome.UsageIngestParams{
    Usage: []metronome.UsageIngestParamsUsage{{
      TransactionID: metronome.F("7e28f511-d66c-4517-91ef-a92c108e56de"),
      Timestamp:     metronome.F("2024-08-01T00:00:00Z"),
      CustomerID:    metronome.F("team@example.com"),
      EventType:     metronome.F("language_model"),
      Properties: metronome.F(map[string]interface{}{
        "model":   "langModel4",
        "user_id": "johndoe",
        "tokens":  1000000,
      }),
    }},
  })

  if err != nil {
    panic(err.Error())
  }
  ```
</CodeGroup>

Le nouvel événement d'utilisation correspond au billable metric défini.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/TrrblT2KR7zYyGbN/images/api-reference/sdks/sdk-billable-metric-event-685727864059c82397e970c9313d34c3.png?fit=max&auto=format&n=TrrblT2KR7zYyGbN&q=85&s=d35de8d4067e32d4eaf2aed156c754f0" alt="Billable metric with a usage event" width="2170" height="750" data-path="images/api-reference/sdks/sdk-billable-metric-event-685727864059c82397e970c9313d34c3.png" />
</Frame>

## 4. Créer un client

Les événements d'utilisation ont un impact sur la facturation des clients ; la prochaine étape consiste donc à créer un client dans Metronome.

Utilisez le SDK pour créer un client, comme dans cet exemple :

<CodeGroup>
  ```python Python theme={null}
  response = client.v1.customers.create(
    name="Example Customer",
    ingest_aliases=[
      "team@example.com"
    ]
  )

  metronome_customer_id = response.data.id
  ```

  ```javascript Node theme={null}
  const customerResponse = await client.v1.customers.create({
    name: "Example Customer",
    ingest_aliases: [
      "team@example.com"
    ]
  });

  const customerId = customerResponse.data.id;
  ```

  ```ruby Ruby theme={null}
  response = client.v1.customers.create(
    name: "Example Customer",
    ingest_aliases: [
      "team@example.com"
    ]
  )

  metronome_customer_id = response.data.id
  ```

  ```go Go theme={null}
  customerResponse, err := client.V1.Customers.New(context.TODO(), metronome.CustomerNewParams{
    Name: metronome.F("Example Customer"),
    IngestAliases: metronome.F([]string{
      "team@example.com",
    }),
  })

  if err != nil {
    panic(err.Error())
  }

  customerID := customerResponse.Data.ID
  ```
</CodeGroup>

Les propriétés utilisées dans cet exemple sont :

* `name`, le nom d'affichage du client dans Metronome.
* `ingest_aliases`, une liste d'identifiants utilisés pour faire correspondre un client Metronome à un événement d'utilisation. Les ingest aliases sont utiles si vous souhaitez commencer à faire circuler de l'utilisation pour les clients avant qu'ils ne soient créés dans Metronome. Pour ce faire, utilisez l'ID de la table client de votre application.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/TrrblT2KR7zYyGbN/images/api-reference/sdks/sdk-customer-8951c5c90f6d572acfe0b66fb69c375a.png?fit=max&auto=format&n=TrrblT2KR7zYyGbN&q=85&s=b4d587d5569f286f4571a93ef13c238c" alt="New customer" width="848" height="344" data-path="images/api-reference/sdks/sdk-customer-8951c5c90f6d572acfe0b66fb69c375a.png" />
</Frame>

Dans l'exemple, vous avez associé le client nouvellement créé à l'ingest alias `team@example.com`, donc l'événement précédent est correctement mis en correspondance. Une fois que le client est configuré pour la facturation dans la section suivante, cet événement contribue à sa facture actuelle.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/TrrblT2KR7zYyGbN/images/api-reference/sdks/sdk-billable-metric-customer-9c43209722c86ae10d972b5674713926.png?fit=max&auto=format&n=TrrblT2KR7zYyGbN&q=85&s=4f2af00f69f7d78e30885f4c25fb678f" alt="Billable metric for the customer" width="2170" height="682" data-path="images/api-reference/sdks/sdk-billable-metric-customer-9c43209722c86ae10d972b5674713926.png" />
</Frame>

## 5. Configurer la tarification et le packaging

Configurez ensuite les prix et le packaging, définis à l'aide de produits et de rate cards.

Dans l'exemple, vous souhaitez facturer votre client en fonction de son utilisation de `langModel4` au tarif de 0,50 \$ par million de jetons.

La première étape consiste à créer un `product` pour votre billable metric. Un produit est l'endroit où vous configurez le billable metric pour la présentation sur la future facture. C'est également là que vous pouvez associer le metric à des éléments de systèmes externes, comme l'ID client Stripe. Découvrez les options de configuration des produits dans la documentation API pour l'endpoint [create product](/fr/api-reference/products/create-a-product).

Créez un produit associé au billable metric, comme dans cet exemple :

<CodeGroup>
  ```python Python theme={null}
  response = client.v1.contracts.products.create(
    name="Language Model 4 Tokens (millions)",
    type="USAGE",
    billable_metric_id=billable_metric_id,  # ID from create billable metric response
    presentation_group_key=["user_id"],
    quantity_conversion={
      "conversion_factor": 1000000,
      "operation": "divide"
    }
  )

  product_id = response.data.id
  ```

  ```javascript Node theme={null}
  const productResponse = await client.v1.contracts.products.create({
    name: "Language Model 4 Tokens (millions)",
    type: "USAGE",
    billable_metric_id: billableMetricId,  // ID from create billable metric response
    presentation_group_key: ["user_id"],
    quantity_conversion: {
      conversion_factor: 1000000,
      operation: "DIVIDE"
    }
  });

  const productId = productResponse.data.id;
  ```

  ```ruby Ruby theme={null}
  response = client.v1.contracts.products.create(
    name: "Language Model 4 Tokens (millions)",
    type: "USAGE",
    billable_metric_id: billable_metric_id,  # ID from create billable metric response
    presentation_group_key: ["user_id"],
    quantity_conversion: {
      conversion_factor: 1000000,
      operation: "divide"
    }
  )

  product_id = response.data.id
  ```

  ```go Go theme={null}
  productResponse, err := client.V1.Contracts.Products.New(context.TODO(), metronome.ContractProductNewParams{
    Name: metronome.F("Language Model 4 Tokens (millions)"),
    Type: metronome.F(metronome.ContractProductNewParamsTypeUsage),
    BillableMetricID: metronome.F(billableMetricId),
    PresentationGroupKey: metronome.F([]string{
      "user_id",
    }),
    QuantityConversion: metronome.F(metronome.QuantityConversionParam{
      ConversionFactor: metronome.F(1000000.0),
      Operation:        metronome.F(metronome.QuantityConversionOperationDivide),
    }),
  })

  if err != nil {
    panic(err.Error())
  }

  productID := productResponse.Data.ID
  ```
</CodeGroup>

Les propriétés utilisées dans cet exemple sont :

* `name`, le nom du produit qui apparaît sur la facture. Souvent une présentation nettoyée du nom du billable metric (`Language Model 4 Tokens (millions)` plutôt que `langModel4`).
* `type`, détermine la manière dont un produit est facturé. Les types pris en charge incluent `usage`, `fixed`, `composite` (pour les pourcentages d'autres produits d'utilisation), et `subscription`.
* `billable_metric_id`, associe la présentation du produit à un billable metric existant.
* `presentation_group_key`, utilisé pour grouper les lignes d'articles sur votre facture selon une valeur de propriété donnée.
* `quantity_conversion`, utilisé pour multiplier ou diviser les quantités affichées sur la facture finale. Par exemple, facturer par million de jetons (mTok) tout en envoyant l'utilisation au niveau du jeton individuel.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/TrrblT2KR7zYyGbN/images/api-reference/sdks/sdk-billable-metric-millions-19186d5f83b1cdad82704ab369e73138.png?fit=max&auto=format&n=TrrblT2KR7zYyGbN&q=85&s=1630f2d2105b45c00bf019065d697d1a" alt="Converted billable metric" width="1248" height="692" data-path="images/api-reference/sdks/sdk-billable-metric-millions-19186d5f83b1cdad82704ab369e73138.png" />
</Frame>

Ensuite, associez un prix au produit en ajoutant des tarifs à une rate card.

Créez une rate card pour votre nouveau produit, comme dans cet exemple :

<CodeGroup>
  ```python Python theme={null}
  response = client.v1.contracts.rate_cards.create(
    name="Language Model List Pricing",
    description="Prices for all language models.",
  )

  rate_card_id = response.data.id

  response = client.v1.contracts.rate_cards.rates.add(
    rate_card_id=rate_card_id,
    product_id=product_id,
    entitled=True,
    rate_type="FLAT",
    price=50,
    starting_at="2024-01-01T00:00:00.000Z"
  )
  ```

  ```javascript Node theme={null}
  const rateCardResponse = await client.v1.contracts.rateCards.create({
    name: "Language Model List Pricing",
    description: "Prices for all language models."
  });

  const rateCardId = rateCardResponse.data.id;

  await client.v1.contracts.rateCards.rates.add({
    rate_card_id: rateCardId,
    product_id: productId,
    entitled: true,
    rate_type: "FLAT",
    price: 50,
    starting_at: "2024-01-01T00:00:00.000Z"
  });
  ```

  ```ruby Ruby theme={null}
  response = client.v1.contracts.rate_cards.create(
    name: "Language Model List Pricing",
    description: "Prices for all language models."
  )

  rate_card_id = response.data.id

  response = client.v1.contracts.rate_cards.rates.add(
    rate_card_id: rate_card_id,
    product_id: product_id,
    entitled: true,
    rate_type: "FLAT",
    price: 50,
    starting_at: "2024-01-01T00:00:00.000Z"
  )
  ```

  ```go Go theme={null}
  rateCardResponse, err := client.V1.Contracts.RateCards.New(context.TODO(), metronome.ContractRateCardNewParams{
    Name:        metronome.F("Language Model List Pricing"),
    Description: metronome.F("Prices for all language models."),
  })

  if err != nil {
    panic(err.Error())
  }

  rateCardID := rateCardResponse.Data.ID
  startingTime, err := time.Parse(time.RFC3339Nano, "2024-01-01T00:00:00.000Z")

  if err != nil {
    panic(err.Error())
  }
  _, err = client.V1.Contracts.RateCards.Rates.Add(context.TODO(), metronome.ContractRateCardRateAddParams{
    RateCardID: metronome.F(rateCardID),
    ProductID:  metronome.F(productID),
    Entitled:   metronome.F(true),
    RateType:   metronome.F(metronome.ContractRateCardRateAddParamsRateTypeFlat),
    Price:      metronome.F(50.0),
    StartingAt: metronome.F(startingTime),
  })

  if err != nil {
    panic(err.Error())
  }
  ```
</CodeGroup>

Les propriétés utilisées dans cet exemple sont :

* `entitled`, un booléen qui indique si un tarif apparaît par défaut sur la facture d'un client. Si `False`, il n'apparaîtra pas sur la facture d'un client à moins d'être remplacé au niveau du contrat.
* `rate_type`, utilisé pour configurer la manière dont un tarif est appliqué à mesure que l'utilisation entre. Les valeurs prises en charge incluent `FLAT` ou `TIERED`.
* `price`, le tarif lui-même. Pour l'USD, les valeurs sont en **cents** (par exemple, `100` = 1,00 \$). Les autres devises utilisent des unités entières. Voir la [dénomination des devises](/fr/guides/pricing-packaging/make-pricing-changes/use-currency-custompricingunits#currency-denomination) pour plus de détails.
* `starting_at`, utilisé pour définir l'heure à laquelle le tarif entre en vigueur. Pour faire évoluer vos tarifs dans le temps, définissez des dates `starting_at` et `ending_before` afin d'assurer des mises à jour de tarification fluides.

Vous pouvez utiliser cette rate card pour tous les SKU de votre catalogue de produits.

## 6. Créer un contrat

Pour commencer à générer des factures pour un client, placez-le sur un contrat. Un contrat est un objet qui représente les termes qu'un client a accepté de payer, généralement basés sur votre rate card. Dans sa version la plus simple, un client peut avoir un contrat de base où il paie les prix de liste prédéfinis ; cela peut couvrir bon nombre de vos cas simples en libre-service. Si vous avez des remises ou des engagements spécifiques négociés par un client, configurez-les dans le contrat en plus des prix de liste de base.

Ajoutez votre client créé à un contrat, comme dans cet exemple qui utilise la rate card Language Model List Pricing :

<CodeGroup>
  ```python Python theme={null}
  response = client.v1.contracts.create(
    customer_id=metronome_customer_id,
    rate_card_id=rate_card_id,
    starting_at="2024-08-01T00:00:00.000Z"
  )
  ```

  ```javascript Node theme={null}
  await client.v1.contracts.create({
    customer_id: customerId,
    rate_card_id: rateCardId,
    starting_at: "2024-08-01T00:00:00.000Z"
  });
  ```

  ```ruby Ruby theme={null}
  response = client.v1.contracts.create(
    customer_id: metronome_customer_id,
    rate_card_id: rate_card_id,
    starting_at: "2024-08-01T00:00:00.000Z"
  )
  ```

  ```go Go theme={null}
  contractStartingTime, err := time.Parse(time.RFC3339Nano, "2024-09-01T00:00:00.000Z")

  if err != nil {
    panic(err.Error())
  }

  contractResponse, err := client.V1.Contracts.New(context.TODO(), metronome.ContractNewParams{
    CustomerID: metronome.F(customerID),
    RateCardID: metronome.F(rateCardID),
    StartingAt: metronome.F(contractStartingTime),
  })

  if err != nil {
    panic(err.Error())
  }

  contractID := contractResponse.Data.ID
  ```
</CodeGroup>

Après la création du contrat, des factures sont générées pour toutes les périodes de facturation qui se sont produites après la date `starting_at`. Les données d'utilisation de la période actuelle sont visibles sur la facture `DRAFT`. Les lignes d'articles des factures brouillons sont mises à jour quelques secondes après que Metronome reçoive les données d'utilisation.

Pour le nouveau contrat de l'exemple, l'utilisation précédente d'un million de jetons a été appliquée.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/TrrblT2KR7zYyGbN/images/api-reference/sdks/sdk-contract1-1baf22de9680a77ea8381e4f6ac75422.png?fit=max&auto=format&n=TrrblT2KR7zYyGbN&q=85&s=7490b51331f5363a8798deb9404e0ac4" alt="New contract" width="1432" height="682" data-path="images/api-reference/sdks/sdk-contract1-1baf22de9680a77ea8381e4f6ac75422.png" />
</Frame>

Ensuite, envoyez quelques événements d'utilisation supplémentaires et observez la mise à jour en temps réel :

<CodeGroup>
  ```python Python theme={null}
  response = client.v1.usage.ingest(
    usage=[
      {
        "transaction_id": "382a3069-d056-4249-824d-d288b51d7743",
        "timestamp": "2024-08-15T04:39:20Z",
        "customer_id": "team@example.com",
        "event_type": "language_model",
        "properties": {
          "model": "langModel4",
          "user_id": "johndoe",
          "tokens": 1000000
        }
      },
      {
        "transaction_id": "db64bf17-f13d-4c19-89cc-acaf878a42c6",
        "timestamp": "2024-08-16T19:11:02Z",
        "customer_id": "team@example.com",
        "event_type": "language_model",
        "properties": {
          "model": "langModel4",
          "user_id": "janedoe",
          "tokens": 5500000
        }
      },
      {
        "transaction_id": "266339fd-2125-4827-afb7-a395a7f0007f",
        "timestamp": "2024-08-17T12:51:32Z",
        "customer_id": "team@example.com",
        "event_type": "language_model",
        "properties": {
          "model": "langModel4",
          "user_id": "johndoe",
          "tokens": 3000000
        }
      },
    ]
  )
  ```

  ```javascript Node theme={null}
  await client.v1.usage.ingest({
    usage: [
      {
        transaction_id: '382a3069-d056-4249-824d-d288b51d7743',
        timestamp: "2024-08-15T04:39:20Z",
        customer_id: 'team@example.com',
        event_type: 'language_model',
        properties: {
          model: "langModel4",
          user_id: "johndoe",
          tokens: 1000000
        }
      },
      {
        transaction_id: 'db64bf17-f13d-4c19-89cc-acaf878a42c6',
        timestamp: "2024-08-16T19:11:02Z",
        customer_id: 'team@example.com',
        event_type: 'language_model',
        properties: {
          model: "langModel4",
          user_id: "janedoe",
          tokens: 5500000
        }
      },
      {
        transaction_id: '266339fd-2125-4827-afb7-a395a7f0007f',
        timestamp: "2024-08-17T12:51:32Z",
        customer_id: 'team@example.com',
        event_type: 'language_model',
        properties: {
          model: "langModel4",
          user_id: "johndoe",
          tokens: 3000000
        }
      },
    ]
  });
  ```

  ```ruby Ruby theme={null}
  response = client.v1.usage.ingest(
    usage: [
      {
        transaction_id: "382a3069-d056-4249-824d-d288b51d7743",
        timestamp: "2024-08-15T04:39:20Z",
        customer_id: "team@example.com",
        event_type: "language_model",
        properties: {
          model: "langModel4",
          user_id: "johndoe",
          tokens: 1000000
        }
      },
      {
        transaction_id: "db64bf17-f13d-4c19-89cc-acaf878a42c6",
        timestamp: "2024-08-16T19:11:02Z",
        customer_id: "team@example.com",
        event_type: "language_model",
        properties: {
          model: "langModel4",
          user_id: "janedoe",
          tokens: 5500000
        }
      },
      {
        transaction_id: "266339fd-2125-4827-afb7-a395a7f0007f",
        timestamp: "2024-08-17T12:51:32Z",
        customer_id: "team@example.com",
        event_type: "language_model",
        properties: {
          model: "langModel4",
          user_id: "johndoe",
          tokens: 3000000
        }
      }
    ]
  )
  ```

  ```go Go theme={null}
  err := client.V1.Usage.Ingest(context.TODO(), metronome.UsageIngestParams{
    Usage: []metronome.UsageIngestParamsUsage{
      {
        TransactionID: metronome.F("382a3069-d056-4249-824d-d288b51d7743"),
        Timestamp:     metronome.F("2024-08-15T04:39:20Z"),
        CustomerID:    metronome.F("team@example.com"),
        EventType:     metronome.F("language_model"),
        Properties: metronome.F(map[string]interface{}{
          "model":   "langModel4",
          "user_id": "johndoe",
          "tokens":  1000000,
        }),
      },
      {
        TransactionID: metronome.F("db64bf17-f13d-4c19-89cc-acaf878a42c6"),
        Timestamp:     metronome.F("2024-08-16T19:11:02Z"),
        CustomerID:    metronome.F("team@example.com"),
        EventType:     metronome.F("language_model"),
        Properties: metronome.F(map[string]interface{}{
          "model":   "langModel4",
          "user_id": "janedoe",
          "tokens":  5500000,
        }),
      },
      {
        TransactionID: metronome.F("266339fd-2125-4827-afb7-a395a7f0007f"),
        Timestamp:     metronome.F("2024-08-17T12:51:32Z"),
        CustomerID:    metronome.F("team@example.com"),
        EventType:     metronome.F("language_model"),
        Properties: metronome.F(map[string]interface{}{
          "model":   "langModel4",
          "user_id": "johndoe",
          "tokens":  3000000,
        }),
      },
    },
  })

  if err != nil {
    panic(err.Error())
  }
  ```
</CodeGroup>

Après actualisation de la facture, les valeurs des trois charges utiles d'événements ci-dessus s'appliquent aux totaux des lignes d'articles en cours. Les clés de groupe précédemment appliquées vous permettent de séparer la présentation de la facture selon l'ID utilisateur associé à l'utilisation.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/TrrblT2KR7zYyGbN/images/api-reference/sdks/sdk-contract2-e0955e079cd3ef6724b4770bc0227a10.png?fit=max&auto=format&n=TrrblT2KR7zYyGbN&q=85&s=7c92485534f8ed794cdc40f611230bf4" alt="Updated contract" width="1424" height="846" data-path="images/api-reference/sdks/sdk-contract2-e0955e079cd3ef6724b4770bc0227a10.png" />
</Frame>
