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

# Generate a signature

Learn how to create a signature for your API requests. This is required for all requests to dLocal’s API.

# What is a signature, and why is it required?

A signature acts as a security mechanism to verify your identity and protect your data when making requests to dLocal’s API. Think of it as a digital fingerprint, created by combining your API credentials, the current timestamp, and the data you're sending. This ensures that every request originates from an authorized source and hasn't been tampered with in transit.

# How to generate a signature

The steps below apply to the standard HMAC-based authentication (not certificate-based). For certificate-based authentication, please refer to [Mutual TLS Certificates](https://docs.dlocal.com/docs/initial-settings#mutual-tls-certificates).

1. **Get your credentials**\
   You'll need your `x-login`, `x-trans-key`, and `secret key`. You can learn how to find them in the [Get API credentials](https://docs.dlocal.com/docs/get-api-credentials) article.

2. **Prepare the data to sign**\
   Concatenate your `x-login`, the current timestamp (`x-date`), and the request body. Concatenate the values as: `x-login + x-date + requestBody` (all as strings, no delimiters).

3. **Generate the signature**\
   Use HMAC SHA256 with your `secret key` to hash the data you have prepared following the previous step.

4. **Add the signature to your request**\
   Include it in the Authorization header.

## Required headers

| Header          | Type   | Description                                                                                                                                          |
| --------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `X-Date`        | String | ISO8601 Datetime with Timezone. Example: `2018-07-12T13:46:28.629Z`                                                                                  |
| `X-Login`       | String | Identifies the merchant making the request. Find your keys in the [Merchant Dashboard](https://dashboard.dlocal.com/settings/integration)            |
| `X-Trans-Key`   | String | Used along with `x-login` to authenticate the request. Find your keys in the [Merchant Dashboard](https://dashboard.dlocal.com/settings/integration) |
| `Content-Type`  | String | Always complete `application/json`                                                                                                                   |
| `X-Version`     | String | Current API Version number: `2.1`                                                                                                                    |
| `User-Agent`    | String | Identifies the application type, operating system, or software version of the requesting user agent                                                  |
| `Authorization` | String | Use the format: `V2-HMAC-SHA256, Signature: <hmac(secretKey, "X-Login+X-Date+RequestBody")>`                                                         |

## Signature differences for Payins and Payouts

> **Note**.  You can start with the basic signature method above. The differences below are relevant when you're ready to implement both payment types.

### Payins signatures

For payment operations (accepting payments):

* Use the **HMAC-SHA256 algorithm** with the format: `V2-HMAC-SHA256, Signature: <signature>`
* Signature data includes: `x-login` + `x-date` + `RequestBody`
* Include as the `Authorization` header in your request

### Payouts signatures

#### Payouts v2

For disbursement operations (sending money):

* Use the **HMAC-SHA256 algorithm** with the signature in hexadecimal lowercase format
* Signature data uses the request payload as the data to be hashed
* The signature must be included in the `Payload-Signature` header

#### Payouts v3

For Payouts API v3 (OAuth-based):

* Signature-based authentication is not required
* Instead, use OAuth2 Bearer Tokens obtained via the `/oauth/token` endpoint
* Include the token in the `Authorization` header in the format:\
  `Authorization: Bearer <YOUR_ACCESS_TOKEN>`

> **Important**. Always check the specific documentation for [Payins](https://docs.dlocal.com/reference/payins-security), [Payouts v2](https://docs.dlocal.com/reference/payouts-security) or [Payouts v3](https://docs.dlocal.com/reference/payouts-security-v3) to ensure you're using the correct authentication method for each flow.

# Using the signature in headers

### For Payins

```json
curl -X POST \
   -H 'X-Date: {x-date}' \
   -H 'X-Login: {x-login}' \
   -H 'X-Trans-Key: {x-trans-key}' \
   -H 'Content-Type: application/json' \
   -H 'X-Version: 2.1' \
   -H 'User-Agent: MerchantTest / 1.0 ' \
   -H 'Authorization: V2-HMAC-SHA256, Signature: {Signature}' \
   -d '{body}'
    https://api.dlocal.com/payments
```

### For Payouts

The signature process differs slightly; specifically, the signature data uses the request payload as the data to be hashed.

You can find detailed requirements in our [Payouts Security](https://docs.dlocal.com/reference/payouts-security)  documentation.

## Examples of HMAC signature generation

Our GitHub repository hosts a variety of signature examples, which can be a valuable resource for understanding implementation details and for reference in your development process.

[Check out signature examples on GitHub > ](https://github.com/tam-dlocal/Starter-Code-Examples)

```javascript Java
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public final class SignatureCalculator {

    private static final String HMAC_ALGORITHM = "HmacSHA256";
    private static final String CHARSET = "UTF-8";

    public static String calculateSignature(String x_Login, String x_Date, String secretKey, String body)
        throws IOException, InvalidKeyException, NoSuchAlgorithmException {

        // Create byte array with the required data for the signature.
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        bout.write(x_Login.getBytes(CHARSET));
        bout.write(x_Date.getBytes(CHARSET));
        bout.write(body.getBytes(CHARSET));

        // Calculate the signature.
        SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes(), HMAC_ALGORITHM);
        Mac mac = Mac.getInstance(HMAC_ALGORITHM);
        mac.init(signingKey);
        byte[] signature = mac.doFinal(bout.toByteArray());

        // Create a String with the signature value.
        Formatter formatter = new Formatter();
        for (byte b : signature) {
            formatter.format("%02x", b);
        }
        return formatter.toString();
    }
}
```
```javascript PHP
$signature = hash_hmac("sha256", "$X-Login$X-Date$RequestBody", $secretKey);
```
```javascript Python
signature = hmac.new(secretKey, X-Login+X-Date+RequestBody, hashlib.sha256).hexdigest()
```
```javascript Ruby
signature = OpenSSL::HMAC.hexdigest('sha256', secretKey, $X-Login + $X-Date + RequestBody)

```
```typescript Typescript
import * as crypto from 'crypto';

class SignatureCalculator {
    calculateSignature(timestamp: string, body?: string): string {
        let message: string = process.env.DLOCAL_X_LOGIN + timestamp;

        if (body) {
            message += body;
        }

        const hmac = crypto.createHmac('sha256', process.env.DLOCAL_SECRET_KEY);
        hmac.update(message, 'utf-8');
        const signature: string = hmac.digest('hex');

        return `V2-HMAC-SHA256, Signature: ${signature}`;
    }
}

// Example usage
const calculator = new SignatureCalculator();
const timestamp = new Date().toISOString(); // Corrected the timestamp
const body = "yourRequestBody";
const result = calculator.calculateSignature(timestamp, body);
console.log(result);
```
```javascript Javascript
function calculateSignature(timestamp, body) {
    let message = process.env.DLOCAL_X_LOGIN + timestamp;

    if (body) {
        message += body;
    }

    const hmac = crypto.createHmac('sha256', process.env.DLOCAL_SECRET_KEY);
    hmac.update(message, 'utf-8');
    const signature = hmac.digest('hex');

    return `V2-HMAC-SHA256, Signature: ${signature}`;
}

// Example usage
const timestamp = new Date().toISOString(); // Set timestamp to current time
const body = "yourRequestBody";
const result = calculateSignature(timestamp, body);
console.log(result);
```
```csharp C#
static string SignatureCalculator(string x_Login, string x_Date, string secretKey, string body)
    {
        string concatenatedData = x_Login + x_Date + body;
        byte[] data = Encoding.UTF8.GetBytes(concatenatedData);
        byte[] keyBytes = Encoding.UTF8.GetBytes(secretKey);

        using (var hmacsha256 = new HMACSHA256(keyBytes))
        {
            byte[] hashBytes = hmacsha256.ComputeHash(data);
            StringBuilder signatureBuilder = new StringBuilder();

            foreach (byte b in hashBytes)
            {
                signatureBuilder.Append(b.ToString("x2"));
            }

            return signatureBuilder.ToString();
        }
    }
```