Code samples

curl, Node.js, Python, PHP and Go

Complete upload flow examples in 5 languages. We assume your API key is in a CBCTHUB_API_KEY environment variable.

curl

bash
# 1. Create exam
RESPONSE=$(curl -sX POST https://cbcthub.com/api/v1/exams \
  -H "Authorization: Bearer $CBCTHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "CBCT mandíbula",
    "patient_name": "Juan Pérez",
    "files": [{ "name": "ct.dcm", "size": 1048576 }]
  }')

EXAM_ID=$(echo "$RESPONSE" | jq -r .exam_id)
UPLOAD_URL=$(echo "$RESPONSE" | jq -r '.upload_urls[0].url')

# 2. Upload to R2
curl -X PUT "$UPLOAD_URL" --data-binary @./ct.dcm

# 3. Confirm
curl -X POST "https://cbcthub.com/api/v1/exams/$EXAM_ID/confirm" \
  -H "Authorization: Bearer $CBCTHUB_API_KEY"

Node.js / TypeScript

typescript
import { readFile, stat } from 'node:fs/promises';

const API = 'https://cbcthub.com/api/v1';
const KEY = process.env.CBCTHUB_API_KEY!;

async function uploadExam(filePath: string, metadata: {
  name: string;
  patient_name?: string;
  patient_id?: string;
}) {
  const fileBuffer = await readFile(filePath);
  const fileSize = (await stat(filePath)).size;
  const fileName = filePath.split('/').pop()!;

  const createRes = await fetch(`${API}/exams`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      ...metadata,
      files: [{ name: fileName, size: fileSize }],
    }),
  });
  const { exam_id, upload_urls } = await createRes.json();

  await fetch(upload_urls[0].url, { method: 'PUT', body: fileBuffer });

  const confirmRes = await fetch(`${API}/exams/${exam_id}/confirm`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${KEY}` },
  });
  return await confirmRes.json();
}

Python

python
import os, requests

API = 'https://cbcthub.com/api/v1'
HEADERS = {'Authorization': f'Bearer {os.environ["CBCTHUB_API_KEY"]}'}

def upload_exam(file_paths, metadata):
    files_meta = [
        {'name': os.path.basename(p), 'size': os.path.getsize(p)}
        for p in file_paths
    ]
    r = requests.post(f'{API}/exams', headers={**HEADERS, 'Content-Type': 'application/json'},
                      json={**metadata, 'files': files_meta})
    r.raise_for_status()
    data = r.json()

    for path, url_info in zip(file_paths, data['upload_urls']):
        with open(path, 'rb') as f:
            requests.put(url_info['url'], data=f.read()).raise_for_status()

    confirm = requests.post(f'{API}/exams/{data["exam_id"]}/confirm', headers=HEADERS)
    return confirm.json()

result = upload_exam(['./ct_001.dcm', './ct_002.dcm'],
                     {'name': 'CBCT mandíbula', 'patient_name': 'Juan Pérez'})
print('Share:', result['share_url'])

PHP

php
<?php
$api = 'https://cbcthub.com/api/v1';
$key = getenv('CBCTHUB_API_KEY');

function api($method, $path, $key, $body = null) {
    global $api;
    $ch = curl_init("$api$path");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST => $method,
        CURLOPT_HTTPHEADER => ["Authorization: Bearer $key", 'Content-Type: application/json'],
        CURLOPT_POSTFIELDS => $body ? json_encode($body) : null,
    ]);
    return json_decode(curl_exec($ch), true);
}

$res = api('POST', '/exams', $key, [
    'name' => 'CBCT mandíbula',
    'patient_name' => 'Juan Pérez',
    'files' => [['name' => 'ct.dcm', 'size' => filesize('./ct.dcm')]],
]);
file_get_contents('./ct.dcm'); // upload bytes to $res['upload_urls'][0]['url']
$final = api('POST', "/exams/{$res['exam_id']}/confirm", $key);
echo $final['share_url'];

Go

go
package main

import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
    "os"
)

const api = "https://cbcthub.com/api/v1"

func main() {
    key := os.Getenv("CBCTHUB_API_KEY")
    info, _ := os.Stat("./ct.dcm")
    body, _ := json.Marshal(map[string]interface{}{
        "name": "CBCT mandíbula",
        "patient_name": "Juan Pérez",
        "files": []map[string]interface{}{
            {"name": "ct.dcm", "size": info.Size()},
        },
    })

    req, _ := http.NewRequest("POST", api+"/exams", bytes.NewReader(body))
    req.Header.Set("Authorization", "Bearer "+key)
    req.Header.Set("Content-Type", "application/json")
    res, _ := http.DefaultClient.Do(req)
    var data struct {
        ExamID     string `json:"exam_id"`
        UploadURLs []struct{ URL string `json:"url"` } `json:"upload_urls"`
    }
    json.NewDecoder(res.Body).Decode(&data)

    f, _ := os.Open("./ct.dcm")
    bs, _ := io.ReadAll(f)
    putReq, _ := http.NewRequest("PUT", data.UploadURLs[0].URL, bytes.NewReader(bs))
    http.DefaultClient.Do(putReq)

    confirmReq, _ := http.NewRequest("POST", api+"/exams/"+data.ExamID+"/confirm", nil)
    confirmReq.Header.Set("Authorization", "Bearer "+key)
    http.DefaultClient.Do(confirmReq)
}