Carbon Property TablesProperty explorer

API guide

Create comparison figures and citation bundles from Python or HTTP. Benchmark your own sample against the published CPT database.

No API key required. Figures, source metadata, and up to ten top results per request are available; bulk measurement downloads are not.

Get started

Use Python 3.10 or newer. The client connects to the public CPT service; it does not download the database.

Terminal
python -m pip install carbon-property-tables==0.4.0

The first argument is the x property; the second is the y property. This example includes commercial reference materials as well as research records.

Python
import carbon_property_tables as cpt

release_id = cpt.release()["release"]["release_id"]

figure = cpt.scatter(
    "specific strength",        # x: N/tex
    "specific cond",            # y: kS m^2/kg
    log_x=True,
    log_y=True,
    release=release_id,
    formats=("svg", "png", "pdf"),
    top=5,
    top_by="y",
)

figure.save_bundle("conductivity-vs-strength")
print(figure.top_table())
# In a notebook, display the figure with: figure

save_bundle() writes SVG, PNG, and PDF figures, a citation list, BibTeX, and a reproducibility manifest. To save one format instead, use figure.save("comparison.svg"); request that format when creating the figure.

Four figure types

Scatter
Compare two reported properties.
Ranked
Highest reported values of the y property.
Trend
The y property against publication year.
Ashby
Logarithmic property comparison with material-family regions.
Python
import carbon_property_tables as cpt

x, y = "specific strength", "specific cond"
options = dict(
    release=cpt.release()["release"]["release_id"],
    log_x=True, log_y=True,
    formats=("svg", "png", "pdf"),
)

for mode in ("scatter", "ranked", "trend", "ashby"):
    figure = getattr(cpt, mode)(x, y, **options)
    figure.save_bundle(mode)

Set log_x and log_y explicitly in Python. Ashby always uses log axes; Trend keeps publication year linear.

Filters and top results

Select material families, form, year, or measurement ranges. The example below compares CNT and carbon fibers with reported densities from 500 to 2,000 kg/m3.

Python
import carbon_property_tables as cpt

figure = cpt.scatter(
    "specific strength", "specific cond",
    log_x=True, log_y=True,
    release=cpt.release()["release"]["release_id"],
    material_family=[
        "CNT_or_CNT_hybrid",
        "carbon_fiber_comparator",
    ],
    form_factor="fiber_yarn",
    measurement_filter=["density:500:2000"],
    top=5, top_by="y",
)
figure.save_bundle("filtered-fibers")
figure.save_top_table("top-five.csv")

measurement_filter uses property:min:max in canonical SI units. Leave a bound empty for no limit. A record missing the filtered property is excluded. top=5, top_by="y" returns the five highest y values; the maximum is ten.

Commercial/spec-sheet records are included unless excluded by a filter. Use peer_reviewed=True for only peer-reviewed sources. For a minimum x-property threshold with the qualifying leader highlighted, see the REST example.

Benchmark your sample

Add a labelled marker without changing the database. Coordinates use the displayed axis units, not the canonical units used in measurement filters.

Python
import carbon_property_tables as cpt
from carbon_property_tables import TemporaryPoint

figure = cpt.scatter(
    "specific strength", "specific cond",
    log_x=True, log_y=True,
    release=cpt.release()["release"]["release_id"],
    form_factor="fiber_yarn",
    temporary=TemporaryPoint(
        x=1.8,                  # N/tex
        y=12.0,                 # kS m^2/kg
        label="My sample",
    ),
    formats=("svg", "png", "pdf"),
)
figure.save_bundle("my-sample")
print(figure.temporary_point)

The response reports axis ranks, percentiles, and Pareto status within the plotted cohort. The sample is temporary, user-supplied, and not a curated CPT measurement.

REST API

Use /api/v1 on this website. Release metadata, the property catalog, and the OpenAPI specification describe the current service.

This request applies a minimum specific strength of 2 N/tex, hides point callouts, and returns all three image formats. minimum_x uses displayed x-axis units. These two settings are supported by the server but require a newer source-checkout client for Python; the published 0.4.0 package examples above do not depend on them.

Terminal
curl --fail-with-body \
  https://carbonnanotubes.onrender.com/api/v1/figures \
  -H 'Content-Type: application/json' \
  -d '{
    "kind": "scatter",
    "x": "specific_strength",
    "y": "specific_electrical_conductivity",
    "x_scale": "log",
    "y_scale": "log",
    "minimum_x": 2.0,
    "show_callouts": false,
    "formats": ["svg", "png", "pdf"],
    "top": 5,
    "top_by": "y",
    "filters": {"form_factor": "fiber_yarn"}
  }' > figure-response.json
Python
import base64
import json
from pathlib import Path

result = json.loads(Path("figure-response.json").read_text())
Path("comparison.svg").write_text(result["images"]["svg"])
for fmt in ("png", "pdf"):
    Path(f"comparison.{fmt}").write_bytes(
        base64.b64decode(result["images"][f"{fmt}_base64"])
    )
Path("comparison.bib").write_text(result["citations"]["bibtex"])
Path("comparison.citations.txt").write_text(
    result["citations"]["copy_all"]
)
# Keep this response and the original request for reproducibility.

For a repeatable request, also pass release with the release_id returned by /api/v1/release. PNG and PDF are base64-encoded in the JSON response; SVG is text.

Processing analysis and source locations

Compare how a named treatment changes thermal and electrical conductivity. The versioned catalog contains 54 source-linked contrasts. Each calculation returns both channel responses, their relative preference, evidence qualifications, and a reproducible receipt.

Python
import json
from urllib.request import Request, urlopen

url = "https://carbonnanotubes.onrender.com/api/v1/analysis/transport"
def analysis(payload):
    request = Request(url, data=json.dumps(payload).encode(),
                      headers={"Content-Type": "application/json"})
    with urlopen(request, timeout=30) as response:
        return json.load(response)

catalog = analysis({"action": "catalog"})
result = analysis({"action": "compare",
    "ids": ["piontkowski2025_preheat", "piraux1985_cucl2"],
    "version": catalog["analysis_version"]})
print(result["result"])
source = analysis({"action": "source",
    "doi": "10.1021/acs.jpcc.5c05657"})
print(source["source"]["locators"])

A thermal preference does not necessarily mean a thermal gain: electrical loss also changes the ratio. Report both responses. Comparisons sharing a source or control are dependent; a treatment label alone does not establish a mechanism.

Connect your own assistant using the MCP setup and scientific contract, or download the MCP adapter package. The adapter calls the same tested server calculations. It returns paper links and figure, table, or page locations, not publisher passages or PDFs. Access and permission to use the original papers remain separate.

Cite and reproduce

  1. Pin the release ID and retain the generated manifest with your figures.
  2. Cite CPT and the original sources in the figure's citation bundle.
  3. Report your properties, units, source classes, and other active filters.
  4. Check specimen identity and measurement conditions before interpreting differences across papers.

The service currently serves one active release. An unavailable release pin fails rather than silently using newer data. Unknown properties, invalid bounds, and unsupported requests return explicit errors; narrow the filters for an empty or overly broad comparison.

Full tutorial and reference examples