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

# Quickstart: DualEntry Public API

> Get a DualEntry API key, make your first authenticated request to the Public API, and confirm the response, all in under five minutes.

Make your first authenticated call to the DualEntry Public API in under five minutes. By the end, you'll have a working API key and a successful response from a live endpoint.

## Get an API key

Ask your DualEntry administrator to generate an API key for you, or see [Give an integration access](/developers/guides/api/api-keys/how-to-give-an-integration-access) if you're the administrator. Every request authenticates with this key in the `X-API-KEY` header. There's no OAuth flow or token exchange to set up.

## Make your first request

Request the invoices collection. Replace `your_api_key_here` with your real key.

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl https://api.dualentry.com/public/v2/invoices \
      -H "X-API-KEY: your_api_key_here" \
      -H "Content-Type: application/json"
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import requests

    headers = {
        "X-API-KEY": "your_api_key_here",
        "Content-Type": "application/json"
    }

    response = requests.get("https://api.dualentry.com/public/v2/invoices", headers=headers)
    print(response.json())
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    fetch('https://api.dualentry.com/public/v2/invoices', {
      headers: {
        'X-API-KEY': 'your_api_key_here',
        'Content-Type': 'application/json'
      }
    })
    .then(response => response.json())
    .then(data => console.log(data));
    ```
  </Tab>

  <Tab title="PHP">
    ```php theme={null}
    <?php
    $ch = curl_init('https://api.dualentry.com/public/v2/invoices');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'X-API-KEY: your_api_key_here',
        'Content-Type: application/json',
    ]);

    $response = curl_exec($ch);
    curl_close($ch);

    echo $response;
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    package main

    import (
    	"fmt"
    	"io"
    	"net/http"
    )

    func main() {
    	req, _ := http.NewRequest("GET", "https://api.dualentry.com/public/v2/invoices", nil)
    	req.Header.Set("X-API-KEY", "your_api_key_here")
    	req.Header.Set("Content-Type", "application/json")

    	resp, _ := http.DefaultClient.Do(req)
    	defer resp.Body.Close()

    	body, _ := io.ReadAll(resp.Body)
    	fmt.Println(string(body))
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.dualentry.com/public/v2/invoices"))
        .header("X-API-KEY", "your_api_key_here")
        .header("Content-Type", "application/json")
        .GET()
        .build();

    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    System.out.println(response.body());
    ```
  </Tab>

  <Tab title="Ruby">
    ```ruby theme={null}
    require 'net/http'
    require 'uri'

    uri = URI('https://api.dualentry.com/public/v2/invoices')
    request = Net::HTTP::Get.new(uri)
    request['X-API-KEY'] = 'your_api_key_here'
    request['Content-Type'] = 'application/json'

    response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(request)
    end

    puts response.body
    ```
  </Tab>
</Tabs>

A successful response returns a `200` status with a paginated list of invoices:

```json theme={null}
{
  "items": [
    { "id": 123, "number": "INV-1001", "amount": "..." }
  ],
  "cursor": null
}
```

<Warning>
  A `403` here almost always means the key is missing a role. See [Errors](/developers/guides/api/core-concepts/errors) for the full list of failure responses.
</Warning>

## Base URL

All requests use `https://api.dualentry.com`, including requests from a sandbox organization, if you're testing an integration before pointing it at production. Your API key is scoped to the organization it was issued from, so there's no separate host to configure; only the key changes between a sandbox and a production integration.

<Info>
  All API requests use HTTPS. The API accepts and returns JSON-formatted data.
</Info>

## Next steps

* **[Authentication](/developers/guides/api/authentication)**: key statuses, roles, and how authorization failures are reported.
* **[Core Concepts](/developers/guides/api/core-concepts/index)**: the mechanics every integration needs to get right, including rate limits, pagination, and idempotent writes.
* **[Versioning](/developers/guides/versioning-policy)**: which version to build against and what counts as a breaking change.
* **[API Reference](/developers/api/resources-v2/invoices/list-invoice-records)**: every endpoint, request and response schema, and parameter.

If you're building a production integration for the partner program rather than a one-off script, see [How Custom Integrations Work](/developers/guides/integrations-and-tools/how-custom-integrations-work).
