PVT API
Contents
PVT API
The PVT calculator models reservoir fluid properties (oil, gas, water) over a pressure range using various correlations, and returns property curves (plots), single‑point reservoir‑condition values (solution), and a stepped property table (results) available in PVT calculator of the pengtools.
Endpoints
All endpoints require the Authorization: Bearer <api_key> header and are subject to rate limiting. The response envelope is always { "success": <bool>, "data": <payload> }
| Method | Path | Purpose |
|---|---|---|
| POST | /pvt-calculator/calc | Synchronous — compute and return the result in the same request |
| POST | /pvt-calculator/calc-async | Asynchronous — enqueue a job, return a {token} |
| GET | /pvt-calculator/{token}/status | Job status and progress |
| GET | /pvt-calculator/{token}/output-data | Job result (same shape as the sync data) |
| GET | /pvt-calculator/{token}/input-data | The input the job was created with |
| POST | /pvt-calculator/{token}/start | Reset and re-run the job |
| POST | /pvt-calculator/{token}/stop | Stop a running job |
| DELETE | /pvt-calculator/{token} | Delete the job |
Use /calc (synchronous) for normal interactive requests — a single PVT model computes in well under a second and the result comes back in the HTTP response.
Use /calc-async only for batch/heavy workloads where you would rather not hold an open HTTP connection. The async path enqueues an api_task row that is picked up by the CalcDaemon worker; you then poll status and fetch output-data. The async job runs the same calculatePvt() code as the sync endpoint, so the result is identical for identical input.
Synchronous request
POST /pvt-calculator/calc
The request body is a JSON object containing PVT calculator attributes plus two optional unit-control keys:
{
"unit_system": "RU",
"defaultFluidType": "OIL",
"maximumPressure": 300,
"reservoirPressure": 300,
"temperature": 90,
"pBubbleInitial": 200,
"rsbInitial": 60,
"isRsbUsedForPb": true,
"sgOil": 0.85,
"sgGas": 0.75,
"sgWater": 1.0
}
On success the endpoint returns HTTP 200 with:
{ "success": true, "data": { "plots": {},"solution": {}, "results": {} } }
Where data carries:
- plots — property curves
- solution — single-point reservoir-condition values
- results — stepped property table
Units
Input field names (e.g., maximumPressure, temperature) carry no unit. The unit system determines how values are interpreted.
unit_system
a shortcut that applies a whole preset of units. Accepted values (case‑insensitive):
- METRIC - Metric system
- FIELD - Field system
Example:
{
"unit_system": "METRIC",
"maximumPressure": 300,
"temperature": 90
}
Attribute units
| Field | METRIC | FIELD |
|---|---|---|
| maximumPressure | ATM | PSIA |
| minimumPressure | ATM | PSIA |
| reservoirPressure | ATM | PSIA |
| pBubbleInitial | ATM | PSIA |
| temperature | CELSIUS | FAHRENHEIT |
| rsbInitial | M3_PER_M3 | SCF_PER_BBL |
| sgOil | SPECIFIC_GRAVITY | API |
| sgGas | SPECIFIC_GRAVITY | SPECIFIC_GRAVITY |
| sgWater | SPECIFIC_GRAVITY | SPECIFIC_GRAVITY |
Input parameter specification
Ranges below are expressed in internal units (the units the validator sees), with common METRIC/FIELD equivalents for convenience.
| Field | Required | Internal unit | Range (internal) | METRIC | FIELD | Notes |
|---|---|---|---|---|---|---|
| defaultFluidType | yes | — | OIL or GAS | — | — | Selects the primary fluid path. WATER is only valid inside forFluid. |
| maximumPressure | yes | PSIA | 25 … 10000 | ≈ 1.7 … 680 ATM | 25 … 10000 psi | Upper bound of the pressure sweep. |
| minimumPressure | no (default 14.6) | PSIA | 14.6 … 10000 | ≈ 1.0 … 680 ATM | 14.6 … 10000 psi | Lower bound of the sweep; must be ≤ maximumPressure. |
| reservoirPressure | yes | PSIA | 25 … 10000 | ≈ 1.7 … 680 ATM | 25 … 10000 psi | Reservoir-condition pressure for solution. |
| temperature | yes | RANKIN | 529.47 … 851.67 | ≈ 21 … 200 °C | ≈ 70 … 392 °F | Reservoir-condition temperature for solution. |
| pBubbleInitial | yes | PSIA | 0 … 20000 | ≈ 0 … 1361 ATM | 0 … 20000 psi | Initial bubble point. See isRsbUsedForPb. |
| rsbInitial | yes (when OIL) | M3_PER_M3 | > 0 | m³·m⁻³ | scf/bbl | Solution GOR at bubble point. |
| sgOil | yes | SPECIFIC_GRAVITY | 0.75 … 0.99 | 0.75 … 0.99 SG | ≈ 11.4 … 57.2 °API | Oil specific gravity. US system accepts API. |
| sgGas | yes | SPECIFIC_GRAVITY | 0.55 … 1.8 | 0.55 … 1.8 SG | 0.55 … 1.8 SG | Gas specific gravity (air = 1). |
| sgWater | yes | SPECIFIC_GRAVITY | 0.9 … 1.2 | 0.9 … 1.2 SG | 0.9 … 1.2 SG | Water specific gravity. |
| isRsbUsedForPb | no (default false) | bool | true / false | — | — | true: derive bubble point from rsbInitial. false: derive GOR from pBubbleInitial. |
| forFluid | no (default all) | — | subset of OIL,GAS,WATER | — | — | Which fluids to compute. |
| needPlots | no (default true) | bool | true / false | — | — | Include the plots block. |
| needSolution | no (default true) | bool | true / false | — | — | Include the solution block. |
| needResults | no (default true) | bool | true / false | — | — | Include the results block. |
Notes
For an oil model, both pBubbleInitial and rsbInitialare required; isRsbUsedForPb decides which one is the input and which is derived.
Response format
On success, data contains up to three blocks, gated by needPlots / needSolution / needResults. Each block is keyed by fluid (OIL, GAS, WATER) — only the fluids in forFluid (and, for oil curves, only when defaultFluidType is OIL) are present.
Plots property curves
Each fluid maps curve names to an array of [pressure, value] pairs, one pair per pressure step (200 steps by default). The pressure axis is in the output pressure unit (see Units section).
| Fluid | Curves |
|---|---|
| OIL | Rs, density, fvf, viscosity, tension, compressibility |
| GAS | ZFactor, densitygas, fvfgas, viscositygas, compressibilitygas |
| WATER | densitywater, fvfwater, viscositywater, compressibilitywater, tensionwater |
Example:
<syntaxhighlight lang="json"> "plots": {
"OIL": {
"Rs": [[14.6, 0.0], [36.4, 5.1], [4351.13, 200.0]],
"fvf": 14.6, 1.02,
"density": 14.6, 812.4
}
} </syntaxhighlight>
