Skip to main content
Kallima runs ImmuneBuilder on the variable region of your variant. mAbs use ABodyBuilder2; nanobodies (no VL chain) use NanoBodyBuilder2. The job takes 1–3 minutes and costs 5 credits.

Submit a job

from kallima import KallimaClient

client = KallimaClient(api_key)

job = client.structure_predictions.submit(variant_id=variant_id)
job.wait(timeout=300)

Read the result

result = job.results  # dict, populated when status == "completed"

print(result["model_used"])        # ABodyBuilder2 | NanoBodyBuilder2
print(result["confidence_score"])  # mean per-residue pLDDT, e.g. 0.87
confidence_score is the mean per-residue pLDDT across the full predicted structure. Values above ~0.85 are well-predicted; values below ~0.60 in a loop indicate structural uncertainty.

CDR loop analysis

for loop in result["cdr_analysis"] or []:
    print(loop["loop"], loop["length"], loop["mean_plddt"])
cdr_analysis is a list of dicts — one per CDR loop — containing the loop label (e.g. H3), residue count, geometry, and mean pLDDT.

Download the PDB

pdb_url is a signed URL that expires 1 hour after the job completes. It is only populated on GET /v1/structure-predictions/{id} — list responses omit it.
import httpx

# job.results["pdb_url"] is already present when fetched via get() or wait()
pdb_url = job.results["pdb_url"]
pdb_bytes = httpx.get(pdb_url).content

with open("structure.pdb", "wb") as f:
    f.write(pdb_bytes)
If the URL has expired, re-fetch the job to rotate it:
job = client.structure_predictions.get(job.id)
pdb_url = job.results["pdb_url"]

Cancel a pending job

client.structure_predictions.cancel(job.id)
Only works while the job is pending. Returns 409 if it has already started running.

List prior predictions for a variant

for job in client.structure_predictions.list(variant_id=variant_id):
    print(job.id, job.status, job["created_at"])
List responses do not include pdb_url. Fetch by ID to get the signed download URL.