> ## 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.

# Construisez avec les SDK Metronome

Metronome fournit des kits de développement logiciel (SDK) puissants conçus pour intégrer de manière transparente 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 implémenter les capacités de Metronome sur différentes plateformes et environnements.

Cette page parcourt un système de facturation basé sur l'utilisation basique 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 fondations de la facturation basée sur la consommation.
3. Créez une métrique facturable pour définir comment Metronome doit agréger et mesurer l'utilisation.
4. Créez un client dans le système et associez-le aux é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 basée sur leur utilisation.

## Fonctionnalités du 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 fonctionnalités principales du SDK comprennent :

* **Le typage fort des points de terminaison et objets Metronome** améliore la productivité des développeurs avec une meilleure autocomplétion et un meilleur support IDE pour les objets Metronome.
* **Le support de la pagination** simplifie le processus de récupération et de gestion des données paginées des services Metronome.
* **Le support automatique des réessais** réessaie par défaut chaque requête en cas d'échec jusqu'à trois fois. Vous pouvez le configurer à n'importe quel nombre de réessais. Utilisez ceci pour gérer automatiquement les erreurs transitoires et les problèmes réseau sans avoir besoin d'implémenter une logique de réessai.

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

## 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 passant 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 passée 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 basé sur l'utilisation s'appuie sur les données d'utilisation capturées des utilisateurs sur votre plateforme. Metronome accepte des charges utiles d'utilisation de tous formats via le point de terminaison [/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([
      {
        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 comprennent :

* `usage`, vous permet de passer plusieurs charges utiles d'événements dans une requête. Metronome prend en charge le passage 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 en fonction de cet ID, vous permettant d'envoyer des événements potentiellement plusieurs fois sans vous soucier 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 du client dans Metronome ou tout autre identifiant client que vous voulez définir. Par exemple, l'e-mail du client ou l'ID interne du client dans votre plateforme. Les é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 regroupement 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 voir tous les événements envoyés à Metronome, allez dans l'onglet **Événements** 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. Mais, il n'a pas encore été apparié avec une métrique pour commencer la mesure ni avec un client dans le système.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/C_lGxKgdkdHt6xoX/images/docs/get-started/developer-sdks/sdk-view-event-73e1747ae1551477facc43cbc57b5d41.png?fit=max&auto=format&n=C_lGxKgdkdHt6xoX&q=85&s=017cf4abb448c3abe89a5ad4dbbaf81f" alt="Voir un événement" width="2172" height="732" data-path="images/docs/get-started/developer-sdks/sdk-view-event-73e1747ae1551477facc43cbc57b5d41.png" />
</Frame>

## 3. Créer une métrique facturable

Une métrique facturable décrit une agrégation par client sur un sous-ensemble d'événements d'utilisation. En configurant une métrique facturable, vous indiquez à Metronome comment faire correspondre les événements d'utilisation aux produits que vous facturez.

Voici un exemple de configuration de métrique facturable 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 comprennent :

* `name`, le nom à donner à votre métrique facturable.
* `event_type_filter`, l'ensemble de valeurs comparées au champ `event_type` dans les événements d'utilisation. Omettez ceci si vous voulez 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 de la métrique facturable et que la propriété n'est pas trouvée dans la charge utile, la métrique facturable ne correspondra pas à l'événement.
* `aggregation_key`, utilisée pour définir la propriété avec la valeur pertinente sur laquelle agréger.
* `aggregation_type`, utilisée pour indiquer à Metronome comment agréger les valeurs spécifiées par l'`aggregation_key` à mesure qu'elles entrent dans le système. Les opérations prises en charge sont `SUM`, `COUNT` et `MAX`.
* `group_keys`, utilisées pour définir des propriétés afin de séparer les données d'utilisation dans différents seaux, similaire à une clause `group by` en SQL. L'exemple ci-dessus a défini `user_id` comme clé de groupe, vous pouvez donc afficher la facture séparée par la quantité de tokens consommée par chaque utilisateur.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/C_lGxKgdkdHt6xoX/images/docs/get-started/developer-sdks/sdk-billable-metric-548bf969fd6260246719c508d04edbbf.png?fit=max&auto=format&n=C_lGxKgdkdHt6xoX&q=85&s=a615b65747c42de87f38c753ea07c3ac" alt="Métrique facturable" width="856" height="940" data-path="images/docs/get-started/developer-sdks/sdk-billable-metric-548bf969fd6260246719c508d04edbbf.png" />
</Frame>

Notez que les métriques facturables ne font correspondre que les événements d'utilisation envoyés après la création de la métrique facturable. Maintenant que vous avez créé la métrique, envoyez un autre événement d'utilisation pour vous assurer 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([
    {
      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 à la métrique facturable définie.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/C_lGxKgdkdHt6xoX/images/docs/get-started/developer-sdks/sdk-billable-metric-event-685727864059c82397e970c9313d34c3.png?fit=max&auto=format&n=C_lGxKgdkdHt6xoX&q=85&s=d0727253a057d5478a33d180b6954873" alt="Métrique facturable avec un événement d'utilisation" width="2170" height="750" data-path="images/docs/get-started/developer-sdks/sdk-billable-metric-event-685727864059c82397e970c9313d34c3.png" />
</Frame>

## 4. Créer un client

Les événements d'utilisation impactent la facturation des clients, donc la prochaine étape est de créer un client dans Metronome.

Utilisez le SDK pour créer un client, similaire à 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 comprennent :

* `name`, le nom d'affichage du client dans Metronome.
* `ingest_aliases`, une liste d'identifiants utilisée pour faire correspondre un client Metronome à un événement d'utilisation. Les alias d'ingestion sont utiles si vous voulez commencer à faire circuler 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/C_lGxKgdkdHt6xoX/images/docs/get-started/developer-sdks/sdk-customer-8951c5c90f6d572acfe0b66fb69c375a.png?fit=max&auto=format&n=C_lGxKgdkdHt6xoX&q=85&s=d8af08c4c5d5262faa8eb79a96e2b6eb" alt="Nouveau client" width="848" height="344" data-path="images/docs/get-started/developer-sdks/sdk-customer-8951c5c90f6d572acfe0b66fb69c375a.png" />
</Frame>

Dans l'exemple, vous avez associé le client nouvellement créé à l'alias d'ingestion `team@example.com`, donc l'événement précédent est correctement apparié. Après avoir configuré le client pour la facturation dans la prochaine section, cet événement contribuera à leur facture actuelle.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/C_lGxKgdkdHt6xoX/images/docs/get-started/developer-sdks/sdk-billable-metric-customer-9c43209722c86ae10d972b5674713926.png?fit=max&auto=format&n=C_lGxKgdkdHt6xoX&q=85&s=45ea14337b820d74f32097f151b69f19" alt="Métrique facturable pour le client" width="2170" height="682" data-path="images/docs/get-started/developer-sdks/sdk-billable-metric-customer-9c43209722c86ae10d972b5674713926.png" />
</Frame>

## 5. Configurer la tarification et le packaging

Ensuite, configurez les prix et le packaging, définis à l'aide de produits et de cartes tarifaires.

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

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

Créez un produit associé à la métrique facturable, similaire à 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.ProductNewParams{
    Name:               metronome.F("Language Model 4 Tokens (millions)"),
    Type:               metronome.F(metronome.ProductNewParamsTypeUsage),
    BillableMetricID:   metronome.F(billableMetricID), // ID from create billable metric response
    PresentationGroupKey: metronome.F([]string{
      "user_id",
    }),
    QuantityConversion: metronome.F(metronome.QuantityConversionParam{
      ConversionFactor: metronome.F(1000000.0),
      Operation:        metronome.F(metronome.QuantityConversionParamOperationDivide),
    }),
  })

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

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

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

* `name`, le nom du produit qui apparaît sur la facture. Souvent une présentation nettoyée du nom de la métrique facturable (`Language Model 4 Tokens (millions)` plutôt que `langModel4`).
* `type`, détermine comment 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 à une métrique facturable existante.
* `presentation_group_key`, utilisée pour regrouper les postes sur votre facture par une valeur de propriété donnée.
* `quantity_conversion`, utilisée pour multiplier ou diviser les quantités affichées sur la facture finale. Par exemple, facturer par million de tokens (mTok) tout en envoyant l'utilisation au niveau du token individuel.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/C_lGxKgdkdHt6xoX/images/docs/get-started/developer-sdks/sdk-billable-metric-millions-19186d5f83b1cdad82704ab369e73138.png?fit=max&auto=format&n=C_lGxKgdkdHt6xoX&q=85&s=84d142db2088f3ec102cc278c58125ee" alt="Métrique facturable convertie" width="1248" height="692" data-path="images/docs/get-started/developer-sdks/sdk-billable-metric-millions-19186d5f83b1cdad82704ab369e73138.png" />
</Frame>

Ensuite, attachez un prix pour le produit en ajoutant des taux à une carte tarifaire.

Construisez une carte tarifaire pour votre nouveau produit, similaire à 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.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 comprennent :

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

Vous pouvez utiliser cette carte tarifaire pour tous les SKU de votre catalogue de produits.

## 6. Créer un contrat

Pour commencer à générer des factures pour un client, mettez-le sur un contrat. Un contrat est un objet qui représente les conditions qu'un client a acceptées de payer, généralement basées sur votre carte tarifaire. Au plus simple, un client peut avoir un contrat basique 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 engagements spécifiques qu'un client a négociés, configurez-les dans le contrat par-dessus les prix de liste de base.

Ajoutez votre client créé à un contrat, similaire à cet exemple qui utilise la carte tarifaire 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 avoir créé le contrat, les 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 dans la facture `DRAFT`. Les postes des factures brouillon se mettent à jour quelques secondes après que Metronome reçoit les données d'utilisation.

Pour le nouveau contrat de l'exemple, l'utilisation précédemment envoyée de 1 million de tokens a été appliquée.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/C_lGxKgdkdHt6xoX/images/docs/get-started/developer-sdks/sdk-contract1-1baf22de9680a77ea8381e4f6ac75422.png?fit=max&auto=format&n=C_lGxKgdkdHt6xoX&q=85&s=a695f736680ef497f5278d9e900b3fe9" alt="Nouveau contrat" width="1432" height="682" data-path="images/docs/get-started/developer-sdks/sdk-contract1-1baf22de9680a77ea8381e4f6ac75422.png" />
</Frame>

Ensuite, envoyez quelques événements d'utilisation supplémentaires et voyez-les se mettre à 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([
    {
      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 avoir actualisé la facture, les valeurs des trois charges utiles d'événements ci-dessus s'appliquent aux totaux courants des postes. Les clés de groupe précédemment appliquées vous permettent de séparer la présentation de la facture par l'ID utilisateur associé à l'utilisation.

<Frame>
  <img src="https://mintcdn.com/metronome-b35a6a36/C_lGxKgdkdHt6xoX/images/docs/get-started/developer-sdks/sdk-contract2-e0955e079cd3ef6724b4770bc0227a10.png?fit=max&auto=format&n=C_lGxKgdkdHt6xoX&q=85&s=bd412035d28304ec4a363217f58883f9" alt="Contrat mis à jour" width="1424" height="846" data-path="images/docs/get-started/developer-sdks/sdk-contract2-e0955e079cd3ef6724b4770bc0227a10.png" />
</Frame>
