> This page is for version 2024-10-01 (default).
> For other versions, use one of these documentation indexes:
> - 2024-10-01 (default): https://docs.getkard.com/2024-10-01/llms.txt
> - Legacy: https://docs.getkard.com/legacy/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.getkard.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.getkard.com/_mcp/server.

# Create Bulk Transactions Upload URL

POST https://rewards-api.getkard.com/v2/issuers/{organizationId}/transactions/uploads
Content-Type: application/json

Generates up to 10 presigned PUT URLs for uploading JSONL transaction files (up to 5GB each) directly
to storage. Each URL is valid for 15 minutes. Use the returned URL to upload the file via an HTTP PUT request with the
binary file content as the body. If a URL expires before the upload completes, you must request a new one.
Files can be uploaded as plain JSONL or as a gzip-compressed file.
Supports both `incomingTransactionsFile` for daily transaction ingestion and `historicalTransactionsFile` for historical transaction ingestion. See the [Historical Transaction Uploads](/2024-10-01/api/integration-guides/historical-transaction-uploads) integration guide for details on the historical flow.
Required scopes: `files:write`

Reference: https://docs.getkard.com/api/transactions/create-bulk-transactions-upload-url

## Authentication

- `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer <token>`, where token is your auth token.

## Servers

- `https://rewards-api.getkard.com` (Production, default)
- `https://test-rewards-api.getkard.com` (Sandbox)

## Request

### Path parameters

- `organizationId` (string, required) — Your issuer organization ID, provided by Kard

### Body (application/json)

This endpoint expects a CreateFileUploadRequestBody.

- `data` (list of CreateFileUploadData, required) — List of file upload requests (1–10 items per request).

## Response

### 201

- `data` (list of FileUploadUrlData, required) — List of created file upload sessions.

## Errors

### 403 Forbidden Error

- `errors` (list of ErrorObject, required)

### 401 Unauthorized Error

- `errors` (list of ErrorObject, required)

### 400 Invalid Request

- `errors` (list of ErrorObject, required)

### 500 Internal Server Error

- `errors` (list of ErrorObject, required)

## Types

### CreateFileUploadData

- `type` (enum, required) — Specifies the category of transaction file being uploaded. Use `incomingTransactionsFile` for new, real-time transactions that need to be processed and matched as they arrive. Use `historicalTransactionsFile` for historical transaction ingestion.
  - Allowed values: `incomingTransactionsFile`, `historicalTransactionsFile`
- `attributes` (CreateFileUploadAttributes, required)

### FileUploadUrlData

- `type` (enum, required) — Specifies the category of transaction file being uploaded. Use `incomingTransactionsFile` for new, real-time transactions that need to be processed and matched as they arrive. Use `historicalTransactionsFile` for historical transaction ingestion.
  - Allowed values: `incomingTransactionsFile`, `historicalTransactionsFile`
- `id` (string, required) — Upload session ID for traceability
- `attributes` (FileUploadUrlAttributes, required)

### ErrorObject

- `status` (string, required) — Status code returned from the request
- `title` (string, required) — Name of error
- `detail` (string, required) — Description of the specific occurance of the error
- `source` (ErrorSource, optional) — An object containing a reference to the primary source of the error
- `id` (string, optional) — The id of the resource which caused the error. Always returned for multi-status errors.

### CreateFileUploadAttributes

- `filename` (string, required) — Name of the file to upload, including extension (e.g. "transaction_12345.jsonl")

### FileUploadUrlAttributes

- `url` (string, required) — Presigned PUT URL for uploading the file directly to storage. Use HTTP PUT with binary body. Expires after 15 minutes.
- `expiresIn` (integer, required) — Time in seconds until the presigned URL expires (900)

### ErrorSource

- `pointer` (string, optional) — A JSON pointer to the value in the request document that caused the error
- `parameter` (string, optional) — A string indicating which URI query parameter caused the error
- `header` (string, optional) — A string indicating the name of a single request header which caused the error

## Examples

### Incoming Transactions Upload URL

**Request**

```json
{
  "data": [
    {
      "type": "incomingTransactionsFile",
      "attributes": {
        "filename": "transaction_12345.jsonl"
      }
    },
    {
      "type": "incomingTransactionsFile",
      "attributes": {
        "filename": "transaction_67890.jsonl"
      }
    }
  ]
}
```

**Response**

```json
{
  "data": [
    {
      "type": "incomingTransactionsFile",
      "id": "2NxKz7TYmqVH8UrjGP1xK3hF2gs",
      "attributes": {
        "url": "https://s3.amazonaws.com/bucket/key1?X-Amz-Algorithm=...",
        "expiresIn": 900
      }
    },
    {
      "type": "incomingTransactionsFile",
      "id": "3PqLa8UZnrWI9VskHQ2yL4iG3ht",
      "attributes": {
        "url": "https://s3.amazonaws.com/bucket/key2?X-Amz-Algorithm=...",
        "expiresIn": 900
      }
    }
  ]
}
```

**SDK Code**

```python Incoming Transactions Upload URL
import requests

url = "https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads"

payload = { "data": [
        {
            "type": "incomingTransactionsFile",
            "attributes": { "filename": "transaction_12345.jsonl" }
        },
        {
            "type": "incomingTransactionsFile",
            "attributes": { "filename": "transaction_67890.jsonl" }
        }
    ] }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Incoming Transactions Upload URL
const url = 'https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"data":[{"type":"incomingTransactionsFile","attributes":{"filename":"transaction_12345.jsonl"}},{"type":"incomingTransactionsFile","attributes":{"filename":"transaction_67890.jsonl"}}]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Incoming Transactions Upload URL
package main

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

func main() {

	url := "https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads"

	payload := strings.NewReader("{\n  \"data\": [\n    {\n      \"type\": \"incomingTransactionsFile\",\n      \"attributes\": {\n        \"filename\": \"transaction_12345.jsonl\"\n      }\n    },\n    {\n      \"type\": \"incomingTransactionsFile\",\n      \"attributes\": {\n        \"filename\": \"transaction_67890.jsonl\"\n      }\n    }\n  ]\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Incoming Transactions Upload URL
require 'uri'
require 'net/http'

url = URI("https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"data\": [\n    {\n      \"type\": \"incomingTransactionsFile\",\n      \"attributes\": {\n        \"filename\": \"transaction_12345.jsonl\"\n      }\n    },\n    {\n      \"type\": \"incomingTransactionsFile\",\n      \"attributes\": {\n        \"filename\": \"transaction_67890.jsonl\"\n      }\n    }\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java Incoming Transactions Upload URL
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"data\": [\n    {\n      \"type\": \"incomingTransactionsFile\",\n      \"attributes\": {\n        \"filename\": \"transaction_12345.jsonl\"\n      }\n    },\n    {\n      \"type\": \"incomingTransactionsFile\",\n      \"attributes\": {\n        \"filename\": \"transaction_67890.jsonl\"\n      }\n    }\n  ]\n}")
  .asString();
```

```php Incoming Transactions Upload URL
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads', [
  'body' => '{
  "data": [
    {
      "type": "incomingTransactionsFile",
      "attributes": {
        "filename": "transaction_12345.jsonl"
      }
    },
    {
      "type": "incomingTransactionsFile",
      "attributes": {
        "filename": "transaction_67890.jsonl"
      }
    }
  ]
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Incoming Transactions Upload URL
using RestSharp;

var client = new RestClient("https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"data\": [\n    {\n      \"type\": \"incomingTransactionsFile\",\n      \"attributes\": {\n        \"filename\": \"transaction_12345.jsonl\"\n      }\n    },\n    {\n      \"type\": \"incomingTransactionsFile\",\n      \"attributes\": {\n        \"filename\": \"transaction_67890.jsonl\"\n      }\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Incoming Transactions Upload URL
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["data": [
    [
      "type": "incomingTransactionsFile",
      "attributes": ["filename": "transaction_12345.jsonl"]
    ],
    [
      "type": "incomingTransactionsFile",
      "attributes": ["filename": "transaction_67890.jsonl"]
    ]
  ]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Historical Transactions Upload URL

**Request**

```json
{
  "data": [
    {
      "type": "historicalTransactionsFile",
      "attributes": {
        "filename": "historical_transactions_2024-10-15.jsonl"
      }
    }
  ]
}
```

**Response**

```json
{
  "data": [
    {
      "type": "historicalTransactionsFile",
      "id": "2Rk3pHqLm9vNwXs1TyBf0Jc4dE",
      "attributes": {
        "url": "https://s3.amazonaws.com/bucket/key1?X-Amz-Algorithm=...",
        "expiresIn": 900
      }
    }
  ]
}
```

**SDK Code**

```python Historical Transactions Upload URL
import requests

url = "https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads"

payload = { "data": [
        {
            "type": "historicalTransactionsFile",
            "attributes": { "filename": "historical_transactions_2024-10-15.jsonl" }
        }
    ] }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Historical Transactions Upload URL
const url = 'https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"data":[{"type":"historicalTransactionsFile","attributes":{"filename":"historical_transactions_2024-10-15.jsonl"}}]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Historical Transactions Upload URL
package main

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

func main() {

	url := "https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads"

	payload := strings.NewReader("{\n  \"data\": [\n    {\n      \"type\": \"historicalTransactionsFile\",\n      \"attributes\": {\n        \"filename\": \"historical_transactions_2024-10-15.jsonl\"\n      }\n    }\n  ]\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Historical Transactions Upload URL
require 'uri'
require 'net/http'

url = URI("https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"data\": [\n    {\n      \"type\": \"historicalTransactionsFile\",\n      \"attributes\": {\n        \"filename\": \"historical_transactions_2024-10-15.jsonl\"\n      }\n    }\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java Historical Transactions Upload URL
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"data\": [\n    {\n      \"type\": \"historicalTransactionsFile\",\n      \"attributes\": {\n        \"filename\": \"historical_transactions_2024-10-15.jsonl\"\n      }\n    }\n  ]\n}")
  .asString();
```

```php Historical Transactions Upload URL
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads', [
  'body' => '{
  "data": [
    {
      "type": "historicalTransactionsFile",
      "attributes": {
        "filename": "historical_transactions_2024-10-15.jsonl"
      }
    }
  ]
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Historical Transactions Upload URL
using RestSharp;

var client = new RestClient("https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"data\": [\n    {\n      \"type\": \"historicalTransactionsFile\",\n      \"attributes\": {\n        \"filename\": \"historical_transactions_2024-10-15.jsonl\"\n      }\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Historical Transactions Upload URL
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["data": [
    [
      "type": "historicalTransactionsFile",
      "attributes": ["filename": "historical_transactions_2024-10-15.jsonl"]
    ]
  ]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://rewards-api.getkard.com/v2/issuers/organization-123/transactions/uploads")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```