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

# CSV Upload

> Generate presigned URLs for bulk logistics CSV uploads

# CSV Upload

Generate presigned S3 upload URLs for bulk importing logistics data via CSV. You can upload requests and/or recharges files in a single call — at least one file name must be provided.

## Request

### Headers

<ParamField header="x-api-key" type="string" required>
  Your API key for authentication

  **Example:** `sk_live_1234567890abcdef`
</ParamField>

<ParamField header="x-organization-id" type="string" required>
  Your organization UUID

  **Example:** `a8315ef3-dd50-43f8-b7ce-d839e68d51fa`
</ParamField>

### Body Parameters

<ParamField body="requests_file_name" type="string">
  Name of the requests CSV file to upload

  **Example:** `routes-jan-2025.csv`
</ParamField>

<ParamField body="recharges_file_name" type="string">
  Name of the recharges CSV file to upload

  **Example:** `fuel-jan-2025.csv`
</ParamField>

<Note>
  At least one of `requests_file_name` or `recharges_file_name` must be provided.
</Note>

## Response

<ResponseField name="requests" type="object | null">
  Presigned URL info for the requests file (null if not requested)
</ResponseField>

<ResponseField name="requests.upload_url" type="string">
  Presigned S3 URL to upload the requests CSV via PUT
</ResponseField>

<ResponseField name="requests.file_name" type="string">
  File name as stored
</ResponseField>

<ResponseField name="requests.file_id" type="string">
  UUID of the created file record
</ResponseField>

<ResponseField name="recharges" type="object | null">
  Presigned URL info for the recharges file (null if not requested)
</ResponseField>

## Example

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  # Step 1: Get presigned URLs for both files
  RESPONSE=$(curl -s -X POST "https://api.dcycle.io/v1/logistics/upload" \
    -H "x-api-key: ${DCYCLE_API_KEY}" \
    -H "x-organization-id: ${DCYCLE_ORG_ID}" \
    -H "Content-Type: application/json" \
    -d '{
      "requests_file_name": "routes-jan-2025.csv",
      "recharges_file_name": "fuel-jan-2025.csv"
    }')

  # Step 2: Upload each file to its presigned URL
  REQUESTS_URL=$(echo $RESPONSE | jq -r '.requests.upload_url')
  RECHARGES_URL=$(echo $RESPONSE | jq -r '.recharges.upload_url')

  curl -X PUT "$REQUESTS_URL" -H "Content-Type: text/csv" --data-binary @routes-jan-2025.csv
  curl -X PUT "$RECHARGES_URL" -H "Content-Type: text/csv" --data-binary @fuel-jan-2025.csv
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import requests
  import os

  headers = {
      "x-api-key": os.getenv("DCYCLE_API_KEY"),
      "x-organization-id": os.getenv("DCYCLE_ORG_ID"),
      "Content-Type": "application/json",
  }

  # Step 1: Get presigned URLs
  response = requests.post(
      "https://api.dcycle.io/v1/logistics/upload",
      headers=headers,
      json={
          "requests_file_name": "routes-jan-2025.csv",
          "recharges_file_name": "fuel-jan-2025.csv",
      },
  )

  result = response.json()

  # Step 2: Upload files
  if result["requests"]:
      with open("routes-jan-2025.csv", "rb") as f:
          requests.put(result["requests"]["upload_url"], data=f, headers={"Content-Type": "text/csv"})
      print(f"Requests file ID: {result['requests']['file_id']}")

  if result["recharges"]:
      with open("fuel-jan-2025.csv", "rb") as f:
          requests.put(result["recharges"]["upload_url"], data=f, headers={"Content-Type": "text/csv"})
      print(f"Recharges file ID: {result['recharges']['file_id']}")
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const axios = require('axios');
  const fs = require('fs');

  const headers = {
    'x-api-key': process.env.DCYCLE_API_KEY,
    'x-organization-id': process.env.DCYCLE_ORG_ID,
    'Content-Type': 'application/json',
  };

  // Step 1: Get presigned URLs
  const { data } = await axios.post('https://api.dcycle.io/v1/logistics/upload', {
    requests_file_name: 'routes-jan-2025.csv',
    recharges_file_name: 'fuel-jan-2025.csv',
  }, { headers });

  // Step 2: Upload files
  if (data.requests) {
    const csv = fs.readFileSync('routes-jan-2025.csv');
    await axios.put(data.requests.upload_url, csv, { headers: { 'Content-Type': 'text/csv' } });
    console.log(`Requests file ID: ${data.requests.file_id}`);
  }

  if (data.recharges) {
    const csv = fs.readFileSync('fuel-jan-2025.csv');
    await axios.put(data.recharges.upload_url, csv, { headers: { 'Content-Type': 'text/csv' } });
    console.log(`Recharges file ID: ${data.recharges.file_id}`);
  }
  ```
</CodeGroup>

### Successful Response

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "requests": {
    "upload_url": "https://s3.eu-west-1.amazonaws.com/dcycle-uploads/...",
    "file_name": "routes-jan-2025.csv",
    "file_id": "file-uuid-1",
    "destination_file_key": "organizations/org-uuid/logistics/requests/file-uuid-1.csv",
    "message": "Upload URL generated successfully"
  },
  "recharges": {
    "upload_url": "https://s3.eu-west-1.amazonaws.com/dcycle-uploads/...",
    "file_name": "fuel-jan-2025.csv",
    "file_id": "file-uuid-2",
    "destination_file_key": "organizations/org-uuid/logistics/recharges/file-uuid-2.csv",
    "message": "Upload URL generated successfully"
  }
}
```

## Common Errors

### 401 Unauthorized

**Cause:** Missing or invalid API key

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{"detail": "Invalid API key for organization", "code": "INVALID_API_KEY"}
```

### 403 Forbidden

**Cause:** The authenticated user is not a member of the organization

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{"detail": "Logged User is not Member of Organization", "code": "LOGGED_USER_NOT_MEMBER"}
```

### 422 Unprocessable Entity

**Cause:** Neither `requests_file_name` nor `recharges_file_name` was provided

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{ "detail": "At least one of requests_file_name or recharges_file_name must be provided." }
```

## Related Endpoints

<CardGroup cols={2}>
  <Card title="List Requests" icon="list" href="/api-reference/logistics/get-requests">
    Browse imported logistics requests
  </Card>

  <Card title="List Recharges" icon="gas-pump" href="/api-reference/logistics/get-recharges">
    Browse imported fuel recharges
  </Card>
</CardGroup>
