/api/transactions/import
POST ASYNCImport specific CloudCoin files from absolute file paths with a transaction memo. Files are moved to the Import folder and processed asynchronously with RAIDA authentication.
Description
The `/api/transactions/import` endpoint provides an advanced way to import CloudCoin files from specific absolute file paths anywhere on the filesystem. This is the more flexible import option compared to `/api/coins/import` (which auto-scans the Import folder), as it lets you:
- Specify exact files: Import from any absolute path on the filesystem
- Add transaction memo: Include a memo for record-keeping and audit trails
- Track progress: Use the task ID to monitor the asynchronous import operation
- Create receipts: Automatic transaction receipt generation in the Receipts folder
This endpoint returns immediately with a task ID. The import operation runs in a background thread, authenticating coins with all 25 RAIDA servers in parallel. Use /api/transactions/task?id=[task_id] to check progress and results.
Step 1: Files are moved (not copied) from absolute paths to [wallet]/Import/
Step 2: Background thread authenticates coins with RAIDA (Detect command 0x010A)
Step 3: POWN strings updated based on RAIDA responses (13+ passes = authentic)
Step 4: Authenticated coins → [wallet]/Bank/
Step 5: Fracked coins (partial passes) → [wallet]/Fracked/
Step 6: Counterfeit coins → [wallet]/Counterfeit/
Step 7: Transaction receipt saved to [wallet]/Receipts/[task_id].import.txt
Files are moved (not copied) using atomic rename operations. The original files will no longer exist at their source paths after the import request is accepted. Ensure:
- Files are not in use by other applications
- You have write permissions for both source and destination paths
- Source and destination are on the same filesystem (for atomic rename)
Use /api/transactions/import when: You need to import from specific paths with memos and receipts
Use /api/coins/import when: You just want to scan and import everything from the Import folder
Request Body Parameters
Send a JSON object in the request body with the following properties:
| Parameter | Type | Required | Description |
|---|---|---|---|
files |
array[string] | Yes | Array of absolute file paths to CloudCoin files (.bin, .stack, .jpeg, .jpg, .png). Maximum 100 files per request. Each path must be absolute and accessible from the server. |
memo |
string | Optional | Transaction memo for record-keeping. Will be included in the receipt file in [wallet]/Receipts/. If omitted, no memo will be recorded. |
{
"files": [
"C:\\Downloads\\coins1.bin",
"C:\\Downloads\\stack25.stack"
],
"memo": "Import from exchange"
}
Response
Returns a JSON object with a task ID to track the asynchronous import operation.
Response Properties
Example Response (Success)
{
"status": "success",
"operation": "import",
"task_id": "Jan-31-25_03-45-12-PM",
"message": "Import task started successfully",
"file_count": 2
}
Example Error Response (Missing Parameter)
{
"error": "Missing required parameter: files (array of absolute paths)"
}
Example Error Response (File Not Found)
{
"error": "File not found: C:\\Downloads\\coins.stack"
}
Examples
JavaScript (fetch) - Complete Workflow
const API_HOST = 'http://localhost:8080';
async function importSpecificFiles(filePaths, memo) {
try {
// Step 1: Start import with POST JSON body
const response = await fetch(`${API_HOST}/api/transactions/import`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
files: filePaths,
memo: memo
})
});
const result = await response.json();
if (result.status === 'success') {
console.log(`Import started with task ID: ${result.task_id}`);
console.log(`Processing ${result.file_count} files`);
// Step 2: Poll for completion
const taskResult = await pollTaskStatus(result.task_id);
// Step 3: Check receipt for details
if (taskResult.status === 'completed') {
console.log('Import complete! Check receipt at:');
console.log(`[wallet]/Receipts/${result.task_id}.import.txt`);
// Step 4: Check updated balance
await checkBalance();
}
} else {
console.error('Import failed:', result.error);
}
} catch (error) {
console.error('Error importing files:', error);
}
}
async function pollTaskStatus(taskId) {
while (true) {
const response = await fetch(`${API_HOST}/api/transactions/task?id=${taskId}`);
const task = await response.json();
console.log(`Status: ${task.status}, Progress: ${task.progress || 0}%`);
if (task.status === 'completed') {
console.log('Import complete:', task);
return task;
} else if (task.status === 'error' || task.status === 'failed') {
console.error('Import failed:', task.message);
throw new Error(task.message);
}
// Poll every second
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
async function checkBalance() {
const response = await fetch(`${API_HOST}/api/wallet/balance`);
const balance = await response.json();
console.log('New wallet balance:', balance);
}
// Example: Import files from Downloads folder
importSpecificFiles([
'C:\\Downloads\\coins1.bin',
'C:\\Downloads\\stack25.stack'
], 'Import from exchange');
cURL - Complete Workflow
# Step 1: Start import with POST JSON body
curl -X POST "http://localhost:8080/api/transactions/import" \
-H "Content-Type: application/json" \
-d '{
"files": [
"C:\\Downloads\\coins1.bin",
"C:\\Downloads\\stack25.stack"
],
"memo": "Import from exchange"
}'
# Response:
# {
# "status": "success",
# "operation": "import",
# "task_id": "Jan-31-25_03-45-12-PM",
# "message": "Import task started successfully",
# "file_count": 2
# }
# Step 2: Poll task status
curl -X GET "http://localhost:8080/api/transactions/task?id=Jan-31-25_03-45-12-PM"
# Step 3: Check receipt (after completion)
# Receipt saved to: [wallet]/Receipts/Jan-31-25_03-45-12-PM.import.txt
# Step 4: Check wallet balance
curl -X GET "http://localhost:8080/api/wallet/balance"
# Example: Single file import with no memo
curl -X POST "http://localhost:8080/api/transactions/import" \
-H "Content-Type: application/json" \
-d '{
"files": ["/tmp/payment.stack"]
}'
Go - Complete Workflow
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
)
const ApiHost = "http://localhost:8080"
type ImportRequest struct {
Files []string `json:"files"`
Memo string `json:"memo,omitempty"`
}
type ImportResponse struct {
Status string `json:"status"`
Operation string `json:"operation"`
TaskID string `json:"task_id"`
Message string `json:"message"`
FileCount int `json:"file_count"`
}
type TaskStatus struct {
Status string `json:"status"`
Progress int `json:"progress"`
Message string `json:"message"`
}
type WalletBalance struct {
TotalValue int `json:"total_value"`
CoinCount int `json:"coin_count"`
}
func importFiles(filePaths []string, memo string) error {
// Step 1: Start import with POST JSON body
requestBody := ImportRequest{
Files: filePaths,
Memo: memo,
}
jsonData, err := json.Marshal(requestBody)
if err != nil {
return err
}
requestURL := fmt.Sprintf("%s/api/transactions/import", ApiHost)
resp, err := http.Post(requestURL, "application/json", bytes.NewBuffer(jsonData))
if err != nil {
return err
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var result ImportResponse
if err := json.Unmarshal(body, &result); err != nil {
return err
}
if result.Status != "success" {
return fmt.Errorf("import failed: %s", result.Message)
}
fmt.Printf("Import started with task ID: %s\n", result.TaskID)
fmt.Printf("Processing %d files\n", result.FileCount)
// Step 2: Poll for completion
if err := pollTaskStatus(result.TaskID); err != nil {
return err
}
// Step 3: Check receipt
fmt.Printf("Receipt saved to: [wallet]/Receipts/%s.import.txt\n", result.TaskID)
// Step 4: Check updated balance
return checkBalance()
}
func pollTaskStatus(taskID string) error {
for {
requestURL := fmt.Sprintf("%s/api/transactions/task?id=%s", ApiHost, taskID)
resp, err := http.Get(requestURL)
if err != nil {
return err
}
body, _ := ioutil.ReadAll(resp.Body)
resp.Body.Close()
var task TaskStatus
if err := json.Unmarshal(body, &task); err != nil {
return err
}
fmt.Printf("Status: %s, Progress: %d%%\n", task.Status, task.Progress)
if task.Status == "completed" {
fmt.Println("Import complete!")
return nil
} else if task.Status == "error" || task.Status == "failed" {
return fmt.Errorf("import failed: %s", task.Message)
}
time.Sleep(1 * time.Second)
}
}
func checkBalance() error {
requestURL := fmt.Sprintf("%s/api/wallet/balance", ApiHost)
resp, err := http.Get(requestURL)
if err != nil {
return err
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var balance WalletBalance
if err := json.Unmarshal(body, &balance); err != nil {
return err
}
fmt.Printf("New wallet balance: %d CloudCoins, Total value: %d\n",
balance.CoinCount, balance.TotalValue)
return nil
}
func main() {
filePaths := []string{
"C:\\Downloads\\coins1.bin",
"C:\\Downloads\\stack25.stack",
}
if err := importFiles(filePaths, "Import from exchange"); err != nil {
fmt.Printf("Error: %v\n", err)
}
}
Related Endpoints
/api/coins/import
Simpler alternative that automatically scans and imports all files from the Import folder. Use this for basic imports without custom file paths or memos.
/api/transactions/task
Check the status and progress of the asynchronous import operation using the task ID. Essential for monitoring long-running imports.
/api/wallet/receipt
View the detailed transaction receipt after import completes. Shows authentication results, coin counts, and POWN strings.
/api/wallet/balance
After import completes, check your wallet balance to see the newly imported coins added to your Bank folder.