TofuPilotTofuPilot
v2 Reference (Preview)Attachments

Initialize upload

Initialize a temporary upload URL for a file and return it along with the upload ID. This is the first step in the attachment upload process.

API v2 Preview

The TofuPilot API v2.0 is currently in public preview and is subject to change as we stabilize until release (planned for Oct 2025).

Access

API KeyAccess LevelDescription
UserFullUsers have full access to uploads
StationFullStations can initialize uploads

Upload Process

Follow these steps to upload attachments to test runs:

Initialize: Call this endpoint to get a temporary upload URL and attachment ID.

Upload: Send your test image to the provided URL using a PUT request. Common formats include:

  • Images: JPEG, PNG, BMP, TIFF for visual test results, defect photos, or equipment screenshots
  • Documents: PDF for test reports, CSV for measurement data, TXT for logs
  • Binary: Any test output files from your equipment or software

Example for uploading a test image:

curl -X PUT "https://storage-url-from-initialize" \
  -H "Content-Type: image/jpeg" \
  --data-binary "@test_result.jpg"

Update Run: Call the Update Run endpoint with the attachment ID to link it to your test run.

Endpoint

POST/v2/attachments
AuthorizationBearer <token>

API key for authentication. Use format: Bearer YOUR_API_KEY

In: header

namestring

Response Body

from tofupilot.v2 import TofuPilot

# Initialize the TofuPilot client
client = TofuPilot()

# Execute the operation
result = client.attachments.initialize(
    name="string"
)

# Handle response
print(result)
{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "upload_url": "string"
}
{
  "message": "Bad request",
  "code": "BAD_REQUEST",
  "issues": []
}
{
  "message": "Forbidden",
  "code": "FORBIDDEN",
  "issues": []
}
{
  "message": "Not found",
  "code": "NOT_FOUND",
  "issues": []
}
{
  "message": "Internal server error",
  "code": "INTERNAL_SERVER_ERROR",
  "issues": []
}
{
  "message": "Bad gateway",
  "code": "BAD_GATEWAY",
  "issues": []
}

How is this guide?