Type Curve 2.0

Hello,
We’re preparing for the Type Curve 2.0 migration and want to share an important upcoming date
and the actions your team may need to take.

Target cutover date: November 7, 2026

Data migration will take place that weekend, with the Type Curve 2.0 cutover occurring as part
of the migration.

What this means for SYNC users
SYNC data will be automatically converted to the new Type Curve 2.0 format and schema as
part of the migration. No conversion work is required on your side.
However, if your workflows or downstream systems ingest Type Curve data from SYNC, please
make sure they are prepared to consume the new structure and format beginning with the
cutover.

What this means for API clients
API clients should begin planning and developing their integrations against the new Type Curve
2.0 format and structure ahead of the November 7 cutover.
The new version changes how some Type Curve data is organized and accessed, so existing V1
integrations should not assume current request and response structures will carry forward
unchanged.

We recommend beginning your V2 ingestion work now so your integration is ready before the
migration weekend.

Additional details are coming.

A few areas of the Type Curve 2.0 contract are still being finalized, including portions of
normalization and other related Type Curve resources. We are intentionally holding those details
until the designs are confirmed so that your team can build against stable information.

We will continue posting updates as these details are finalized, including additional migration
guidance and confirmed API contract information.

Please plan around the November 7, 2026 target date, and watch for additional Type Curve 2.0 updates as we get closer to cutover.


Type Curve 2.0 — Technical Migration Guide

Customer integration guidance for the November 2026 cutover

Target cutover: November 7, 2026
Data migration is planned for that weekend. All current Type Curve data will be converted automatically to the Type Curve 2.0 format and schema. SYNC consumers and API clients must be ready to ingest and work with the V2 structure at cutover.

Audience API developers, data engineers, integration owners
Scope Type Curve 2.0 migration and ingestion changes
Cutover target November 7, 2026
Status Implementation guidance; additional specifications will be published as they are confirmed

This guide intentionally excludes implementation details that are still being finalized. Updated contract details will be published when confirmed.

Contents

  1. Migration overview
  2. Required actions by integration type
  3. V2 API conventions
  4. Type curve resource changes
  5. Fits resource changes
  6. Segment compatibility
  7. Volumes endpoint
  8. Creating and updating type curves
  9. Responses, status codes, and headers
  10. Normalization guidance
  11. Representative wells: expected per-phase rep collapse
  12. Specifications still being finalized
  13. Cutover readiness checklist
  14. Validation scenarios

1. Migration overview

Type Curve 2.0 introduces a revised API structure and data contract. The target cutover date is November 7, 2026, with data migration planned for that weekend.

The migration affects clients differently depending on whether they consume Type Curve data through SYNC or directly through the API.

Integration Migration behavior Customer action
SYNC All current Type Curve data is converted automatically to the V2 format and schema as part of the migration. Update downstream ingestion, mapping, and validation logic so it accepts the new V2 structure.
API All current Type Curve data is also converted automatically. After cutover, V2 GET endpoints return the migrated data in the new structure. Implement and test V2 read, ingestion, and write workflows before cutover. Existing Type Curve data does not need to be recreated.

Cutover planning assumption
Use November 7, 2026 as the current target date for implementation planning. We will continue posting migration updates as remaining details are confirmed.


2. Required actions by integration type

2.1 SYNC consumers

Existing Type Curve data is converted automatically during the migration. For SYNC consumers, downstream compatibility is still your responsibility: systems that read Type Curve data from SYNC should be updated to recognize the V2 structure and field behavior.

  • Review schema mappings and deserialization logic for fields that moved or were renamed.
  • Confirm that omitted optional fields are handled correctly; V2 may omit an absent field instead of returning null.
  • Validate downstream assumptions about where fits and normalization data are located.
  • Run representative ingestion tests before the cutover weekend.

2.2 API clients

API clients should treat this as an integration migration rather than a base-path-only version change. Existing Type Curve data will be converted automatically and can be retrieved from the V2 GET endpoints after cutover, but several read and write operations move to new routes or use revised request and response contracts.

  • Implement V2 reads using the new Type Curve, fits, and volumes routes.
  • Do not recreate existing Type Curve records solely for the migration; migrated records can be read from the V2 GET endpoints.
  • Update write workflows so Type Curve metadata and fit data are written separately.
  • Switch collection updates to PATCH semantics and identify Type Curves by id.
  • Update validation for renamed, removed, and relocated fit fields.
  • Handle V2 response status codes and required request parameters.

3. V2 API conventions

3.1 Base path

/v2/projects/{projectId}/type-curves

3.2 Absent fields are omitted

A V2 response may omit a field that has no value instead of returning the field with a null value. This convention applies across the V2 Type Curve payloads in this guide.

Compatibility check
If your integration distinguishes between “field not present” and “field present with null,” update that logic before cutover.

3.3 IDs remain valid across cutover

Existing Type Curve id values are preserved through migration. Integrations that already store Type Curve ids can continue using those ids after cutover.

For update workflows, prefer id as the stable identifier rather than name.

3.4 Collection behavior retained

Capability V2 behavior
Read record limit 2500
Write record limit 100
Default page size 25
Pagination Cursor and skip/take are retained
Sortable/filterable fields name, createdAt, updatedAt, id

4. Type curve resource changes

4.1 Type Curve object

The Type Curve root object becomes more focused in V2. Fit data is no longer embedded on the Type Curve resource, and regressionType moves to each phase fit.

V1 example

{
  "id": "5f971a8f6749f60012dcb93a",
  "name": "TC1",
  "forecast": "5e272bed4b97ed00132f2271",
  "regressionType": "rate",
  "wells": ["5e272d38b78910dd2a1bd691"],
  "createdAt": "2026-08-01T00:00:00.000Z",
  "updatedAt": "2026-08-14T00:00:00.000Z",
  "fits": {
    "oil": {},
    "gas": {},
    "water": {}
  }
}

V2 example

{
  "id": "5f971a8f6749f60012dcb93a",
  "name": "TC1",
  "forecast": "5e272bed4b97ed00132f2271",
  "wells": ["5e272d38b78910dd2a1bd691"],
  "createdAt": "2026-08-01T00:00:00.000Z",
  "updatedAt": "2026-08-14T00:00:00.000Z"
}
V1 field/behavior V2 Migration impact
regressionType at Type Curve root Moves to each phase fit Read regression type from the fit resource instead of the Type Curve root.
fits embedded on Type Curve Moves to GET /{id}/fits Issue a separate request when fit data is required.
id, name, forecast, wells, createdAt, updatedAt Unchanged Existing mappings can remain in place.

4.2 Confirmed route changes

V1 operation V2 successor
GET /type-curves GET /v2/projects/{projectId}/type-curves
GET /type-curves/{id} GET /v2/projects/{projectId}/type-curves/{id}
GET /{id}/fits/daily GET /v2/projects/{projectId}/type-curves/{id}/volumes?resolution=daily
GET /{id}/fits/monthly GET /v2/projects/{projectId}/type-curves/{id}/volumes?resolution=monthly
POST /type-curves POST /v2/projects/{projectId}/type-curves, then PUT /v2/projects/{projectId}/type-curves/{id}/fits
PUT /type-curves PATCH /v2/projects/{projectId}/type-curves
DELETE /type-curves DELETE /v2/projects/{projectId}/type-curves
HEAD /type-curves HEAD /v2/projects/{projectId}/type-curves
GET /head Removed in V2

5. Fits resource changes

GET /v2/projects/{projectId}/type-curves/{id}/fits

Fits are keyed by phase. If a phase is absent, the phase key is omitted rather than returned as null.

5.1 Example V2 response

{
  "oil": {
    "fitType": "rate",
    "regressionType": "rate",
    "eurPercentileMatched": true,
    "best": { "segments": [] },
    "p10": { "segments": [] },
    "p50": { "segments": [] },
    "p90": { "segments": [] },
    "updatedAt": "2026-08-14T00:00:00.000Z"
  },
  "gas": {
    "fitType": "ratio",
    "regressionType": "rate",
    "eurPercentileMatched": false,
    "ratio": {
      "basePhase": "oil",
      "best": { "segments": [] },
      "p10": { "segments": [] },
      "p50": { "segments": [] },
      "p90": { "segments": [] }
    },
    "updatedAt": "2026-08-14T00:00:00.000Z"
  }
}

5.2 Field mapping

V1 V2 Action
type fitType Rename the field in readers and writers. Values remain rate or ratio.
best / p10 / p50 / p90 Same No series-name change for rate fits.
ratio.{best,p10,p50,p90} Same No series-name change for ratio fits.
ratio.{series}.basePhase ratio.basePhase Read one basePhase value from the ratio object.
basePhase at fit level ratio.basePhase Use only within ratio fits.
regressionType Read regression type per phase fit.
eurPercentileMatched New response field indicating whether EUR-matched segments were retained.
resolution Removed from fit Do not expect or send this field on the V2 fit object.
align Removed from fit Do not expect or send this field on the V2 fit object.
normalize Removed from fit Do not expect or send this field on the V2 fit object.
normalizations Moves to normalization sub-resource Do not expect this key from GET /{id}/fits.

5.3 EUR field behavior

The eur value is not returned from read operations. Integrations should not depend on eur round-tripping through the fit payload; EUR is derived from segment data.

5.4 Fit provenance: removed computation-state fields

A V2 fit response does not identify the alignment, normalization state, or resolution used when the fit was computed. The fields resolution, align, and normalize are not present on the V2 fit resource.

Do not infer or reconstruct those values from another resource. If your integration currently uses these fields as provenance for a stored fit, update that workflow so an absent value is treated as unknown rather than replaced with a plausible value from elsewhere.

This distinction is important for downstream charting, reconciliation, and audit logic: a value describing a current view or workflow state is not necessarily the state used to compute a previously stored fit.


6. Segment compatibility

The forecast segment structure used inside Type Curve fits is unchanged. If your integration already parses the segment object, the segment parser itself does not need to be rewritten; only the path used to reach the segments changes.

{
  "segmentIndex": 1,
  "segmentType": "arps_modified",
  "startDate": "2020-01-01",
  "endDate": "2050-12-31",
  "qStart": 1000.0,
  "qEnd": 12.5,
  "b": 1.1,
  "diEffSec": 0.85,
  "diNominal": 0.0032,
  "realizedDSwEffSec": 0.08,
  "targetDSwEffSec": 0.08,
  "swDate": "2024-06-01",
  "qSw": 45.0,
  "flatValue": null,
  "slope": null
}

Supported segment types remain: arps, arps_inc, arps_modified, exp_dec, exp_inc, flat, linear, and empty. Field names, units, and supported date bounds remain unchanged.

Low-risk migration path
If your consumer only uses fits.{phase}.best.segments today, keep the segment parsing logic and update the API path and surrounding fit-object navigation.


7. Volumes endpoint

GET /v2/projects/{projectId}/type-curves/{id}/volumes

Daily and monthly volume reads move to a single V2 route. The resolution query parameter selects the requested granularity.

7.1 Request examples

GET /v2/projects/{projectId}/type-curves/{id}/volumes?resolution=daily
GET /v2/projects/{projectId}/type-curves/{id}/volumes?resolution=monthly

resolution is required. If it is missing or invalid, the endpoint returns 400.

7.2 Response body compatibility

The volumes response body remains compatible with V1.

[
  {
    "date": "2023-09-01",
    "oil": { "best": 504, "p10": 504, "p50": 504, "p90": 504 },
    "gas": { "best": 100, "p10": 222, "p50": 333, "p90": 4444 },
    "water": { "best": 7854, "p10": 6523, "p50": 98, "p90": 32 }
  }
]

8. Creating and updating type curves

8.1 Creation changes from one call to two

In V1, a Type Curve and its fits can be created in a single request. In V2, create the Type Curve first, then write fit data to the fits sub-resource.

V1: single create request

POST /v1/projects/{projectId}/type-curves
{
  "name": "TC1",
  "forecast": "5e272bed4b97ed00132f2271",
  "regressionType": "rate",
  "wells": ["5e272d38b78910dd2a1bd691"],
  "fits": {
    "oil": {
      "type": "rate",
      "resolution": "monthly",
      "normalizations": [],
      "best": {},
      "p10": {},
      "p50": {},
      "p90": {}
    },
    "gas": {
      "type": "rate",
      "resolution": "monthly",
      "normalizations": [],
      "best": {},
      "p10": {},
      "p50": {},
      "p90": {}
    },
    "water": {
      "type": "rate",
      "resolution": "monthly",
      "normalizations": [],
      "best": {},
      "p10": {},
      "p50": {},
      "p90": {}
    }
  }
}

V2: step 1 — create Type Curve

POST /v2/projects/{projectId}/type-curves
{
  "name": "TC1",
  "forecast": "5e272bed4b97ed00132f2271",
  "wells": ["5e272d38b78910dd2a1bd691"]
}

V2: step 2 — write fits

PUT /v2/projects/{projectId}/type-curves/{id}/fits
{
  "oil": {
    "fitType": "rate",
    "regressionType": "rate",
    "best": { "segments": [] },
    "p10": { "segments": [] },
    "p50": { "segments": [] },
    "p90": { "segments": [] }
  }
}

Important write workflow change
Creating the Type Curve does not create fit data. If your workflow needs fits, issue the follow-up PUT /{id}/fits request and validate that fit data is present before treating the migration as complete.

8.2 V2 fit write rules

Do not send a working V1 fit payload unchanged to V2. V2 rejects resolution and normalizations on fit writes, so both fields must be removed before submitting the request.

V1 behavior V2 behavior
All three phases required when fits are present Any subset of phases may be written; omitted phases are left unchanged.
resolution required on each phase fit Rejected in V2. Remove resolution from the fit write payload.
normalizations required on each phase fit Rejected in V2. Remove normalizations from the fit write payload.
type required fitType required.
Rate fit requires best/p10/p50/p90 Unchanged.
Ratio fit requires ratio and excludes top-level series Unchanged.

8.3 Collection updates: PUT becomes PATCH

Behavior V1 PUT V2 PATCH
Update model Replacement/upsert Merge
Match key name id
Omitted fields May be removed Left unchanged
Rename behavior Can create a separate record Updates the existing id
Success status 207 200

Because ids are preserved through cutover, API clients can update their matching logic to use id before the migration weekend.


9. Responses, status codes, and headers

9.1 Status codes

Situation Response
POST / batch write success 207 Multi-Status; successful items return 201 with the new id
PATCH success 200
PUT /{id}/fits success 200
Volumes request without a valid resolution 400
V1 Type Curve route after cutover 410 Gone
Method not allowed 405 with Allow
Throttled or temporarily unavailable 429 or 503 with Retry-After

Clients should validate both the top-level response and per-item results for batch writes.

9.2 Response headers

Endpoint Headers
HEAD /type-curves Link + X-Query-Count
GET /type-curves Link
GET /{id}/volumes Link

If your integration requires a query count, use HEAD. Do not depend on X-Total-Count for Type Curve collection reads.


10. Normalization guidance

Normalization remains part of Type Curve 2.0, but its request and response contract is still being finalized. The detailed schema will be published when it is confirmed.

The following migration guidance can be used now:

  • Normalization is not being removed.
  • Two-factor normalization continues in V2.
  • Clients that consume peak normalization values will continue to receive peak in V2.
  • Normalization moves out of fits.{phase} into a dedicated normalization sub-resource.
  • GET /{id}/fits will not return a normalizations key.

Do not hard-code an unpublished normalization schema
If your integration reads or writes normalization data, isolate that work behind a migration adapter and apply the final request/response mapping when the specification is published.

10.1 Expected behavior differences

Clients that compare V2 normalization outputs directly with V1 should expect value differences. The calculation behavior changes in the following ways:

  • Peak is no longer based on a 30-day smoothed value.
  • Resolution is uniform per phase rather than per well.
  • Manual cell exclusion applies to production data only.

Because of these behavior changes, validation should focus on the documented V2 calculation behavior rather than exact equality with V1 normalization values.


11. Representative wells: expected per-phase rep collapse

The representative-wells endpoint returns a per-phase object for each well, including a rep flag. In V1, rep is tracked independently per phase, so a well can be representative for the oil fit but not the gas fit.

In Type Curve 2.0, representative-well membership is stored once per Type Curve rather than once per phase. Where that carries through to the API response, oil.rep, gas.rep, and water.rep are expected to return the same value for a given well.

The V2 contract for this endpoint is still being finalized, so treat this as expected behavior rather than a published guarantee; we will confirm the final shape in a later update. We are flagging it now because this change can return 200 while altering results, so it may not surface in testing unless you look for it specifically.

11.1 What to check now

Search your integration for logic that compares rep across phases, or that reads rep for one phase and applies it to that phase alone. Common examples include:

  • Selecting wells for a per-phase analysis.
  • Reconciling representative-well counts phase by phase.
  • Branching on a condition such as oil.rep !== gas.rep.

If representative-well membership becomes Type Curve-level in the final V2 contract, that logic will stop finding phase-to-phase differences in rep.

11.2 Who is affected

Type Curves whose well assignments were created in the ComboCurve UI can carry per-phase rep values. Those integrations should explicitly test representative-well results during migration validation.

Type Curves created through the V1 REST API cannot carry independent rep membership by phase: the API write path has always marked a well representative for all three phases at once. If every Type Curve you read was also created through the V1 REST API, your rep values are already uniform across phases and this expected change does not affect you.

11.3 Unchanged per-phase fields

The other per-phase fields on this endpoint remain genuinely per phase and are not affected by the expected rep collapse:

  • eur
  • dataFrequency
  • eurPll
  • forecastType
  • hasData
  • hasForecast
  • valid

12. Specifications still being finalized

Some Type Curve 2.0 surfaces are still being designed. To avoid requiring customers to rework integrations against provisional contracts, detailed schemas for these areas are intentionally not included in this guide.

Area What to plan for now
Normalization request/response schema The capability remains available and moves to a dedicated sub-resource. Detailed contract information will be published when confirmed.
Representative wells See Section 11 for the expected rep behavior. The final V2 endpoint contract is still being finalized and will be confirmed in a later update.
Lookup-table rule structure Wait for the confirmed V2 specification before changing parsing or write logic.
Risking fields associated with lookup-table rules The V2 specification is still being finalized. Confirmed details will be released with the lookup-table rule specification.
Econ-model risking This is a separate resource and is unchanged for this migration. No customer action is required for econ-model risking.

We will continue posting updates as these areas are finalized and will provide implementation details when they are ready for customer use.


13. Cutover readiness checklist

  • Inventory every Type Curve V1 route used by your integration.
  • Update Type Curve collection and item reads to the V2 base path.
  • Move fit reads to GET /{id}/fits.
  • Update fit field mappings, including typefitType and regressionType relocation.
  • Handle omitted fields correctly rather than assuming null.
  • Move daily/monthly reads to /volumes and always send resolution.
  • Split Type Curve creation and fit creation into two operations.
  • Remove resolution and normalizations from V2 fit write payloads; V2 rejects these fields.
  • Update downstream logic so missing fit provenance (alignment, normalization state, and resolution) remains unknown rather than being inferred from another resource.
  • Use id for collection update matching and implement PATCH merge semantics.
  • Update status-code handling, including 207 batch responses and 410 for V1 after cutover.
  • For SYNC, validate that downstream ingestion accepts the converted V2 structure.
  • Review representative-well logic for phase-specific rep comparisons and test whether your integration depends on oil.rep, gas.rep, and water.rep differing.
  • For normalization consumers, prepare for behavior differences and wait for the confirmed schema before finalizing the adapter.
  • Complete pre-cutover integration tests using representative Type Curves and phase combinations.

14. Validation scenarios

The following scenarios are recommended for pre-cutover testing.

Scenario Expected V2 result
Read a Type Curve with fit data Type Curve metadata is returned without embedded fits; a separate GET /{id}/fits returns phase fits.
Read a Type Curve with a missing phase The missing phase key is omitted rather than returned as null.
Read daily volumes Request includes resolution=daily and response structure matches the existing volume series shape.
Create a Type Curve with fits POST creates metadata; a follow-up PUT /{id}/fits stores fit data.
Update one phase only PUT /{id}/fits can include only the phase being changed; other phases remain unchanged.
Patch a Type Curve name PATCH identifies the Type Curve by id and updates in place.
Compare V1 and V2 normalization outputs Values may differ according to V2 calculation behavior; exact V1 equality is not expected.
Call a V1 Type Curve route after cutover 410 Gone.
Read fit provenance fields alignment, normalization state, and resolution are not available from the V2 fit response; the integration does not infer them from another resource.
Compare representative-well rep across phases Explicitly test whether the integration depends on phase-specific rep differences. V2 is expected to return the same rep value for oil, gas, and water for a given well; the final endpoint contract will be confirmed later.

Customer Technical Migration Guide • Target cutover: November 7, 2026