# Authentication

{% hint style="info" %}
All requests to the Discloud API must include an **API Token** in the `api-token` header.

If you don't have a token yet, generate or retrieve it in your Discloud dashboard. (Replace this note with the exact dashboard link or a screenshot.)
{% endhint %}

***

## ⚙️ How It Works

{% stepper %}
{% step %}
You generate a unique [token](/en/faq/general-questions/how-can-i-get-my-discloud-api-token.md) linked to your account.
{% endstep %}

{% step %}
For every HTTP request include the header: `api-token: YOUR_TOKEN_HERE`.
{% endstep %}

{% step %}
The token authenticates and authorizes actions on behalf of your account (never share it).
{% endstep %}

{% step %}
Use the `/user` endpoint to quickly validate the token.
{% endstep %}
{% endstepper %}

***

## 📤 Sending the Token

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X GET \
  -H "api-token: $DISCLOUD_TOKEN" \
  https://api.discloud.app/v2/user
```

{% endtab %}

{% tab title="Node.js (fetch)" %}

```javascript
import fetch from "node-fetch";

async function getCurrentUser() {
  const res = await fetch("https://api.discloud.app/v2/user", {
    headers: { "api-token": process.env.DISCLOUD_TOKEN },
  });

  if (!res.ok) {
    console.error("Request failed:", res.status, await res.text());
    return;
  }
  const data = await res.json();
  console.log(data);
}
```

{% endtab %}

{% tab title="Node.js (discloud.app SDK)" %}

```javascript
// Install first: npm i discloud.app
const { discloud } = require("discloud.app");

async function validateToken() {
  try {
    const user = await discloud.login("DISCLOUD_API_TOKEN");
    console.log("Authenticated user:", user);
  } catch (e) {
    console.error("Invalid token or network error:", e.message);
  }
}
```

{% endtab %}
{% endtabs %}

***

## 🛡 Securing the Token

{% hint style="warning" %}
Never commit your token (e.g. to Git). Store it in environment variables ([`.env`](/en/faq/general-questions/.env-file.md), CI/CD secrets, etc.).
{% endhint %}

📌 Best practices:

* Use environment variables instead of hard‑coding.
* Rotate the token periodically (e.g. every 90 days).
* Revoke and regenerate immediately if you suspect exposure.
* Restrict who can access infrastructure where the variable is stored.

***

## ⚡ Quick Token Verification

Call `/user` right after setting the environment variable. If you get HTTP 200 with user data, authentication is working.

{% hint style="info" %}
You can also update the user locale (e.g. `en-US`) through `/locale/{locale}` to validate another authenticated route.
{% endhint %}

***

## 📚 Related Endpoints References

The operations below require the `api-token` header:

## Get current user information

> Returns information about the authenticated user

```json
{"openapi":"3.0.4","info":{"title":"Discloud API","version":"2.0.0"},"tags":[{"name":"User","description":"Operations about users"}],"servers":[{"url":"https://api.discloud.app/v2","description":"API Server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"api-token"}},"schemas":{"UserResponse":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"},"user":{"$ref":"#/components/schemas/User"}}},"User":{"type":"object","properties":{"userID":{"type":"string","description":"The unique identifier of the user"},"totalRamMb":{"type":"integer","description":"Total RAM allocated to the user (in MB)"},"ramUsedMb":{"type":"integer","description":"RAM currently being used by the user (in MB)"},"subdomains":{"type":"array","items":{"type":"string"},"description":"List of subdomains owned by the user"},"customdomains":{"type":"array","items":{"type":"string"},"description":"List of custom domains owned by the user"},"apps":{"type":"array","items":{"type":"string"},"description":"List of application IDs owned by the user"},"plan":{"type":"string","description":"The subscription plan of the user"},"locale":{"type":"string","description":"The language/locale"},"lastDataLeft":{"type":"object","properties":{"days":{"type":"integer","description":"Days remaining in the current plan"},"hours":{"type":"integer","description":"Hours remaining in the current plan"},"minutes":{"type":"integer","description":"Minutes remaining in the current plan"},"seconds":{"type":"integer","description":"Seconds remaining in the current plan"}},"description":"Time remaining in the current plan"},"planDataEnd":{"type":"string","format":"date-time","description":"End date of the current plan"}}},"Error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}}}},"paths":{"/user":{"get":{"tags":["User"],"summary":"Get current user information","description":"Returns information about the authenticated user","operationId":"getCurrentUser","responses":{"200":{"description":"Successful operation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"401":{"description":"Authentication error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.discloud.com/en/api-and-integrations/api-overview/authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
