# Authenticate

import { Badge } from "zudoku/ui/Badge";

<div className="flex flex-wrap gap-2 not-prose mb-4">
  <Badge variant="outline">Getting Started</Badge>
  <Badge variant="secondary" className="font-mono text-xs">
    POST /v1/auth/:org
  </Badge>
</div>

Exchange the client credentials for an access token, and build the request headers every other
recipe uses.

<Recipe
  language={["python", "javascript"]}
  steps={[
    {
      title: "Set the credentials",
      body: "The three parts of the credentials are issued by SecuriThings. See [Authentication](/guides/authentication).",
      code: {
        python:
          'import json\n\nimport requests\n\nBASE = "https://api.securithings.com"\nORGANIZATION = "<organization>"\nCLIENT_ID = "<client-id>"\nCLIENT_SECRET = "<client-secret>"',
        javascript:
          'const BASE = "https://api.securithings.com";\nconst ORGANIZATION = "<organization>";\nconst CLIENT_ID = "<client-id>";\nconst CLIENT_SECRET = "<client-secret>";',
      },
    },
    {
      title: "Request a token",
      body: "`client_id` and `client_secret` are sent using Basic Authentication.",
      code: {
        python:
          'response = requests.post(\n    f"{BASE}/v1/auth/{ORGANIZATION}",\n    auth=(CLIENT_ID, CLIENT_SECRET),\n)\nresponse.raise_for_status()',
        javascript:
          'const credentials = Buffer.from(\n  `${CLIENT_ID}:${CLIENT_SECRET}`,\n).toString("base64");\n\nconst response = await fetch(\n  `${BASE}/v1/auth/${ORGANIZATION}`,\n  {\n    method: "POST",\n    headers: {\n      Authorization: `Basic ${credentials}`,\n    },\n  },\n);\nif (!response.ok) {\n  throw new Error(response.statusText);\n}',
      },
    },
    {
      title: "Build the request headers",
      body: "`headers` is the value passed to every request in the recipes that follow.",
      code: {
        python:
          'body = response.json()\naccess_token = body["access_token"]\nheaders = {"Authorization": f"Bearer {access_token}"}',
        javascript:
          "const body = await response.json();\nconst accessToken = body.access_token;\nconst headers = {\n  Authorization: `Bearer ${accessToken}`,\n};",
      },
    },
    {
      title: "Build the result",
      body: "A token is valid for one hour by default. Request a new one after it expires.",
      code: {
        python:
          'result = {\n    "access_token": access_token,\n    "expires_in": body["expires_in"],\n}\n\nprint(json.dumps(result, indent=2))',
        javascript:
          "const result = {\n  access_token: accessToken,\n  expires_in: body.expires_in,\n};\n\nconsole.log(JSON.stringify(result, null, 2));",
      },
    },
  ]}
  response={`{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "expires_in": 3600
}`}
/>
