> ## 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 a presigned URL for bulk commuting periods CSV upload

# CSV Upload

Generate a presigned S3 URL for bulk importing employee commuting periods via CSV. After uploading the file, the system processes each row to create commuting period records and trigger emission calculations.

## 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="file_name" type="string" required>
  Name of the CSV file to upload

  **Example:** `commuting-data-2025.csv`
</ParamField>

## CSV Format

The CSV file should contain the following columns:

| Column             | Required    | Description                                                       |
| ------------------ | ----------- | ----------------------------------------------------------------- |
| `employee_email`   | Yes         | Employee email for lookup                                         |
| `employee_name`    | No          | Employee name (fallback if email not found)                       |
| `start_date`       | Yes         | Period start date (YYYY-MM-DD)                                    |
| `end_date`         | Yes         | Period end date (YYYY-MM-DD)                                      |
| `commuting_type`   | Yes         | `in_itinere` or `in_labore`                                       |
| `transport_type`   | Yes         | car, bus, metro, train, bicycle, walking, telecommuting, etc.     |
| `vehicle_size`     | Conditional | small/medium/large (required for car)                             |
| `fuel_type`        | Conditional | petrol, diesel, electric, hybrid, etc.                            |
| `renewable_energy` | Conditional | yes/no/do\_not\_know (for electric vehicles)                      |
| `carpool`          | Conditional | true/false (required for car)                                     |
| `total_km`         | Yes         | Distance per trip (km)                                            |
| `daily_trips`      | Yes         | Number of daily trips                                             |
| `weekly_travels`   | No          | Days of week, semicolon-separated (e.g., `0;1;2;3;4` for Mon-Fri) |
| `origin`           | No          | Origin address                                                    |
| `destination`      | No          | Destination address                                               |

## Response

<ResponseField name="upload_url" type="string">
  Presigned S3 URL — upload your CSV via PUT to this URL
</ResponseField>

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

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

<ResponseField name="destination_file_key" type="string">
  S3 object key where the file will be stored
</ResponseField>

<ResponseField name="message" type="string">
  Confirmation message
</ResponseField>

<ResponseField name="organization_id" type="string">
  UUID of the organization the file belongs to
</ResponseField>

## Example

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  # Step 1: Get presigned URL
  RESPONSE=$(curl -s -X POST "https://api.dcycle.io/v1/employee-historic/bulk/csv" \
    -H "x-api-key: ${DCYCLE_API_KEY}" \
    -H "x-organization-id: ${DCYCLE_ORG_ID}" \
    -H "Content-Type: application/json" \
    -d '{"file_name": "commuting-data-2025.csv"}')

  # Step 2: Upload CSV to presigned URL
  UPLOAD_URL=$(echo $RESPONSE | jq -r '.upload_url')
  curl -X PUT "$UPLOAD_URL" -H "Content-Type: text/csv" --data-binary @commuting-data-2025.csv

  echo "File ID: $(echo $RESPONSE | jq -r '.file_id')"
  ```

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

  # Step 1: Get presigned URL
  response = requests.post(
      "https://api.dcycle.io/v1/employee-historic/bulk/csv",
      headers={
          "x-api-key": os.getenv("DCYCLE_API_KEY"),
          "x-organization-id": os.getenv("DCYCLE_ORG_ID"),
          "Content-Type": "application/json",
      },
      json={"file_name": "commuting-data-2025.csv"},
  )

  result = response.json()

  # Step 2: Upload CSV
  with open("commuting-data-2025.csv", "rb") as f:
      requests.put(result["upload_url"], data=f, headers={"Content-Type": "text/csv"})

  print(f"File ID: {result['file_id']}")
  ```

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

  // Step 1: Get presigned URL
  const { data } = await axios.post('https://api.dcycle.io/v1/employee-historic/bulk/csv', {
    file_name: 'commuting-data-2025.csv',
  }, {
    headers: {
      'x-api-key': process.env.DCYCLE_API_KEY,
      'x-organization-id': process.env.DCYCLE_ORG_ID,
      'Content-Type': 'application/json',
    },
  });

  // Step 2: Upload CSV
  const csv = fs.readFileSync('commuting-data-2025.csv');
  await axios.put(data.upload_url, csv, { headers: { 'Content-Type': 'text/csv' } });

  console.log(`File ID: ${data.file_id}`);
  ```
</CodeGroup>

### Successful Response

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "upload_url": "https://s3.eu-west-1.amazonaws.com/dcycle-uploads/...",
  "file_name": "commuting-data-2025.csv",
  "file_id": "file-uuid",
  "destination_file_key": "organizations/org-uuid/employee-commuting/file-uuid.csv",
  "message": "Upload URL generated successfully",
  "organization_id": "org-uuid"
}
```

## 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:** Missing required field (`file_name`)

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": [
    {
      "loc": ["body", "file_name"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}
```

## Related Endpoints

<CardGroup cols={2}>
  <Card title="List Commuting Periods" icon="list" href="/api-reference/employees/commuting-periods/list">
    Browse imported commuting periods
  </Card>

  <Card title="Create Commuting Period" icon="plus" href="/api-reference/employees/commuting-periods/create">
    Create a single commuting period manually
  </Card>
</CardGroup>
