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

# Making API Requests

> Making a request to the Smartcar v3 API is a simple HTTP call. Examples for tokens, data, commands, and webhook verification in Node.js, Python, Ruby, Go, and Java.

Making a request to the Smartcar API is simple. Each endpoint is a standard HTTP call, so you can read data, send commands, and verify webhooks straight from your server in any language, without a backend SDK. This page shows each common task with examples in Node.js, Python, Ruby, Go, and Java.

To receive vehicle data, use [event-driven webhooks](/docs/integrations/webhooks/overview) rather than polling: Smartcar pushes updates to your server as they arrive. Use the requests below for on-demand reads and to send commands.

You need two things:

* An **access token**, obtained with the OAuth 2.0 Client Credentials flow. Tokens are valid for one hour and there is no refresh token. Request a new one when it expires. See [API Authentication](/docs/getting-started/how-to/api-authentication).
* A **user ID** (`sc-user-id`), captured from the Connect redirect. Signal reads and commands require it.

Webhook signature verification uses your **Application Management Token**, not the access token.

<Info>
  Moving an existing v2 integration off per-vehicle tokens? See the [Migration Guide](/docs/getting-started/how-to/m2m/migration-guide) for the phased rollout, database schema changes, and rollback plan.
</Info>

## Get an access token

<CodeGroup>
  ```javascript Node.js theme={null}
  const res = await fetch('https://iam.smartcar.com/oauth2/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'client_credentials',
      client_id: process.env.SMARTCAR_CLIENT_ID,
      client_secret: process.env.SMARTCAR_CLIENT_SECRET,
    }),
  });
  const { access_token } = await res.json();
  ```

  ```python Python theme={null}
  import os, requests

  res = requests.post('https://iam.smartcar.com/oauth2/token', data={
      'grant_type': 'client_credentials',
      'client_id': os.environ['SMARTCAR_CLIENT_ID'],
      'client_secret': os.environ['SMARTCAR_CLIENT_SECRET'],
  })
  access_token = res.json()['access_token']
  ```

  ```ruby Ruby theme={null}
  require 'net/http'
  require 'json'

  res = Net::HTTP.post_form(URI('https://iam.smartcar.com/oauth2/token'), {
    'grant_type' => 'client_credentials',
    'client_id' => ENV['SMARTCAR_CLIENT_ID'],
    'client_secret' => ENV['SMARTCAR_CLIENT_SECRET'],
  })
  access_token = JSON.parse(res.body)['access_token']
  ```

  ```go Go theme={null}
  form := url.Values{}
  form.Set("grant_type", "client_credentials")
  form.Set("client_id", os.Getenv("SMARTCAR_CLIENT_ID"))
  form.Set("client_secret", os.Getenv("SMARTCAR_CLIENT_SECRET"))

  res, err := http.PostForm("https://iam.smartcar.com/oauth2/token", form)
  if err != nil {
      return err
  }
  defer res.Body.Close()

  var body struct {
      AccessToken string `json:"access_token"`
  }
  json.NewDecoder(res.Body).Decode(&body)
  accessToken := body.AccessToken
  ```

  ```java Java theme={null}
  String form = "grant_type=client_credentials"
      + "&client_id=" + System.getenv("SMARTCAR_CLIENT_ID")
      + "&client_secret=" + System.getenv("SMARTCAR_CLIENT_SECRET");

  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://iam.smartcar.com/oauth2/token"))
      .header("Content-Type", "application/x-www-form-urlencoded")
      .POST(HttpRequest.BodyPublishers.ofString(form))
      .build();

  HttpResponse<String> response = HttpClient.newHttpClient()
      .send(request, HttpResponse.BodyHandlers.ofString());
  // Parse response.body() for "access_token" with your JSON library.
  ```
</CodeGroup>

## Retrieve vehicle data

Read all signals for a vehicle with `GET /vehicles/{vehicleId}/signals`. For a single signal, use `GET /vehicles/{vehicleId}/signals/{signalCode}`.

<CodeGroup>
  ```javascript Node.js theme={null}
  const res = await fetch(
    `https://vehicle.api.smartcar.com/v3/vehicles/${vehicleId}/signals`,
    { headers: { Authorization: `Bearer ${accessToken}`, 'sc-user-id': userId } }
  );
  const signals = await res.json();
  ```

  ```python Python theme={null}
  res = requests.get(
      f'https://vehicle.api.smartcar.com/v3/vehicles/{vehicle_id}/signals',
      headers={'Authorization': f'Bearer {access_token}', 'sc-user-id': user_id},
  )
  signals = res.json()
  ```

  ```ruby Ruby theme={null}
  uri = URI("https://vehicle.api.smartcar.com/v3/vehicles/#{vehicle_id}/signals")
  req = Net::HTTP::Get.new(uri)
  req['Authorization'] = "Bearer #{access_token}"
  req['sc-user-id'] = user_id

  res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
  signals = JSON.parse(res.body)
  ```

  ```go Go theme={null}
  url := "https://vehicle.api.smartcar.com/v3/vehicles/" + vehicleID + "/signals"
  req, _ := http.NewRequest("GET", url, nil)
  req.Header.Set("Authorization", "Bearer "+accessToken)
  req.Header.Set("sc-user-id", userID)

  res, err := http.DefaultClient.Do(req)
  if err != nil {
      return err
  }
  defer res.Body.Close()
  ```

  ```java Java theme={null}
  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://vehicle.api.smartcar.com/v3/vehicles/" + vehicleId + "/signals"))
      .header("Authorization", "Bearer " + accessToken)
      .header("sc-user-id", userId)
      .GET()
      .build();

  HttpResponse<String> response = HttpClient.newHttpClient()
      .send(request, HttpResponse.BodyHandlers.ofString());
  ```
</CodeGroup>

## Issue a command

Commands are `POST /vehicles/{vehicleId}/commands/...`, for example `security/lock`, `security/unlock`, `charge/start`, `charge/stop`, `charge/set-limit`, and `navigation/set-destination`. Commands that take parameters send them as a JSON body. Locking a vehicle takes no body.

<CodeGroup>
  ```javascript Node.js theme={null}
  const res = await fetch(
    `https://vehicle.api.smartcar.com/v3/vehicles/${vehicleId}/commands/security/lock`,
    { method: 'POST', headers: { Authorization: `Bearer ${accessToken}`, 'sc-user-id': userId } }
  );
  const result = await res.json();
  ```

  ```python Python theme={null}
  res = requests.post(
      f'https://vehicle.api.smartcar.com/v3/vehicles/{vehicle_id}/commands/security/lock',
      headers={'Authorization': f'Bearer {access_token}', 'sc-user-id': user_id},
  )
  result = res.json()
  ```

  ```ruby Ruby theme={null}
  uri = URI("https://vehicle.api.smartcar.com/v3/vehicles/#{vehicle_id}/commands/security/lock")
  req = Net::HTTP::Post.new(uri)
  req['Authorization'] = "Bearer #{access_token}"
  req['sc-user-id'] = user_id

  res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
  result = JSON.parse(res.body)
  ```

  ```go Go theme={null}
  url := "https://vehicle.api.smartcar.com/v3/vehicles/" + vehicleID + "/commands/security/lock"
  req, _ := http.NewRequest("POST", url, nil)
  req.Header.Set("Authorization", "Bearer "+accessToken)
  req.Header.Set("sc-user-id", userID)

  res, err := http.DefaultClient.Do(req)
  if err != nil {
      return err
  }
  defer res.Body.Close()
  ```

  ```java Java theme={null}
  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://vehicle.api.smartcar.com/v3/vehicles/" + vehicleId + "/commands/security/lock"))
      .header("Authorization", "Bearer " + accessToken)
      .header("sc-user-id", userId)
      .POST(HttpRequest.BodyPublishers.noBody())
      .build();

  HttpResponse<String> response = HttpClient.newHttpClient()
      .send(request, HttpResponse.BodyHandlers.ofString());
  ```
</CodeGroup>

## Verify a webhook signature

Every webhook carries an `SC-Signature` header with an HMAC-SHA256 of the raw body, keyed by your Application Management Token. Verify it before processing the payload. Full per-language examples are in [Payload Verification](/docs/integrations/webhooks/payload-verification), and initial endpoint setup is in [Callback URI Verification](/docs/integrations/webhooks/callback-verification).

## Next steps

<CardGroup cols={2}>
  <Card title="API Authentication" icon="key" href="/docs/getting-started/how-to/api-authentication">
    Set up client credentials and obtain access tokens.
  </Card>

  <Card title="Payload Verification" icon="shield-check" href="/docs/integrations/webhooks/payload-verification">
    Verify webhook signatures without an SDK.
  </Card>
</CardGroup>
