Skip to content

Contract Management

Contract Management

DELPHOS manages health insurance contracts with temporal pricing — every price adjustment (reajuste) creates a new contract period, ensuring events are always billed at the configuration valid on the event date, not the current date.


Key Concepts

ConceptDescription
ConvenioA master insurance plan (Unimed, Amil, SUS, or self-pay). Created once per payer.
Contract PeriodA time-bounded pricing configuration within a convenio. Contains CBHPM version, percentage, overrides, and copay rules.
ReajusteA price adjustment that closes the current period and creates a new one, preserving the historical record.
SnapshotA point-in-time view of the complete pricing configuration for audit and billing.
OverrideA procedure-specific price that takes priority over the CBHPM table price.

Convenio (Insurance Plan) CRUD

Create a convenio

POST /v1/scheduling/convenios
FieldTypeRequiredDefaultDescription
namestringYesDisplay name (max 255 chars)
ans_codestringNonullANS registration code (unique per tenant)
payment_typestringYes"particular", "convenio", or "sus"
cbhpm_table_versionstringNonullCBHPM table version (max 10 chars)
requires_card_numberbooleanNofalseWhether patient must present insurance card
requires_authorizationbooleanNofalseWhether prior authorization is required
copay_enabledbooleanNofalseWhether copay (coparticipacao) applies
default_copay_percentdecimalNonullDefault copay percentage (0-100)
default_copay_max_centsintegerNonullMaximum copay in centavos
contact_infoobjectNonullStructured contact details
integration_codestringNonullExternal billing system code
notesstringNonullAdministrative notes
CodeMeaning
201Convenio created
409Duplicate name or ANS code
422Validation error
Terminal window
curl -X POST "https://your-instance.delphos.app/v1/scheduling/convenios" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Unimed Rio",
"ans_code": "393321",
"payment_type": "convenio",
"cbhpm_table_version": "2024",
"requires_card_number": true,
"copay_enabled": true,
"default_copay_percent": 30,
"default_copay_max_cents": 15000
}'

List convenios

GET /v1/scheduling/convenios
ParameterTypeDefaultDescription
is_activebooleannullFilter by active status
offsetinteger0Pagination offset
limitinteger50Records per page (max 200)
Terminal window
curl "https://your-instance.delphos.app/v1/scheduling/convenios?is_active=true&limit=10" \
-H "x-api-key: YOUR_API_KEY"

Validate convenio eligibility

Before booking an appointment, verify that a provider accepts a specific convenio for the requested appointment type.

POST /v1/scheduling/convenio/validate
FieldTypeRequiredDescription
provider_profile_idUUIDYesProvider to check
convenio_idUUIDYesConvenio to validate
appointment_type_idUUIDYesAppointment type to verify
CodeMeaning
200Eligibility result returned
404Provider or convenio not found
422Ineligible — convenio not accepted or appointment type not covered
Terminal window
curl -X POST "https://your-instance.delphos.app/v1/scheduling/convenio/validate" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider_profile_id": "550e8400-e29b-41d4-a716-446655440001",
"convenio_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"appointment_type_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
}'

Provider-Convenio Linking

Providers must be explicitly linked to the convenios they accept.

POST /v1/scheduling/providers/{provider_id}/convenios
FieldTypeRequiredDescription
convenio_idUUIDYesConvenio to link
CodeMeaning
201Link created
404Provider or convenio not found
409Provider already accepts this convenio

List provider convenios

GET /v1/scheduling/providers/{provider_id}/convenios

Remove a convenio from a provider

DELETE /v1/scheduling/providers/{provider_id}/convenios/{convenio_id}

Performs a soft-delete — the link is deactivated, not permanently removed.


Particular Prices

Convenios with payment_type: "particular" (self-pay) can have a dedicated price catalog. This catalog defines procedure-level prices for patients paying out of pocket.

Create a particular price

POST /v1/scheduling/convenios/{convenio_id}/particular-prices
FieldTypeRequiredDescription
procedure_codestringYesProcedure identifier (e.g. TUSS code, max 50 chars)
procedure_namestringYesHuman-readable description (max 500 chars)
price_centsintegerYesPrice in centavos (>= 0)
notesstringNoAdministrative notes
metadataobjectNoStructured metadata
CodeMeaning
201Price entry created
404Convenio not found
409Duplicate procedure code
422Convenio is not particular type
Terminal window
curl -X POST "https://your-instance.delphos.app/v1/scheduling/convenios/CONVENIO_ID/particular-prices" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"procedure_code": "10101012",
"procedure_name": "Consulta em consultorio",
"price_cents": 25000
}'

List particular prices

GET /v1/scheduling/convenios/{convenio_id}/particular-prices
ParameterTypeDefaultDescription
include_inactivebooleanfalseInclude soft-deleted entries
searchstringnullSearch by code or name (max 100 chars)
offsetinteger0Pagination offset
limitinteger50Records per page (max 200)

Update a particular price

PUT /v1/scheduling/convenios/{convenio_id}/particular-prices/{price_id}

Full replacement (PUT semantics). All fields are required.

Delete a particular price

DELETE /v1/scheduling/convenios/{convenio_id}/particular-prices/{price_id}

Soft-delete — the record is deactivated, not permanently removed.

Bulk create

POST /v1/scheduling/convenios/{convenio_id}/particular-prices/bulk

Create up to 100 prices in a single transaction. Duplicates within the batch are skipped and reported in the response summary.

FieldTypeRequiredDescription
itemsarrayYesList of price objects (max 100)

Response:

{
"created": [{ "id": "...", "procedure_code": "10101012", "price_cents": 25000, ... }],
"created_count": 8,
"skipped_count": 2,
"skipped_codes": ["10101012", "10101039"]
}

Contract Periods

Contract periods are time-bounded pricing configurations within a convenio. Each period records a CBHPM table version, percentage, and optional procedure overrides. Periods follow a lifecycle: draft -> active -> closed (manual) or expired (automatic, via lifecycle processing).

Create a contract period

POST /v1/scheduling/convenios/{convenio_id}/contracts
FieldTypeRequiredDefaultDescription
start_datedateYesValidity start date
end_datedateNonullValidity end date (null = open-ended)
cbhpm_table_versionstringNonullCBHPM table version (max 10 chars)
cbhpm_percentagedecimalNonullCBHPM percentage (0-100)
notesstringNonullAdministrative notes
metadataobjectNonullStructured metadata

New periods are created in draft status. end_date must be strictly after start_date when provided.

CodeMeaning
201Period created in draft status
404Convenio not found
409Overlapping period dates
422Validation error (e.g. end_date before start_date)
Terminal window
curl -X POST "https://your-instance.delphos.app/v1/scheduling/convenios/CONVENIO_ID/contracts" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"start_date": "2026-01-01",
"end_date": "2026-12-31",
"cbhpm_table_version": "2024",
"cbhpm_percentage": 70,
"notes": "Annual contract 2026"
}'

List contract periods

GET /v1/scheduling/convenios/{convenio_id}/contracts
ParameterTypeDefaultDescription
statusstringnullFilter by status: draft, active, terminated, expired, renewed
include_inactivebooleanfalseInclude soft-deleted periods
offsetinteger0Pagination offset
limitinteger50Records per page (max 200)

Get a specific period

GET /v1/scheduling/convenios/{convenio_id}/contracts/{period_id}

Get period active on a specific date

GET /v1/scheduling/convenios/{convenio_id}/contracts/at-date
ParameterTypeRequiredDescription
datedateYesThe reference date to look up

This endpoint returns the contract period whose validity range contains the given date — critical for temporal pricing queries.

Update a draft period

PUT /v1/scheduling/convenios/{convenio_id}/contracts/{period_id}

Only periods in draft status can be updated (full replacement semantics). Active, terminated, and expired periods are immutable.

Delete a draft period

DELETE /v1/scheduling/convenios/{convenio_id}/contracts/{period_id}

Only draft periods can be deleted.


Period Lifecycle Transitions

Activate a period

PATCH /v1/scheduling/convenios/{convenio_id}/contracts/{period_id}/activate

Transitions a draft period to active status. Once active, the period becomes immutable and is used for pricing calculations.

CodeMeaning
200Period activated
404Period not found
422Invalid state (not in draft)

Terminate a period

PATCH /v1/scheduling/convenios/{convenio_id}/contracts/{period_id}/terminate

Transitions an active period to terminated status. The period remains queryable for historical pricing but no longer applies to new events.


Reajuste (Price Adjustment)

A reajuste closes the current period and creates a new one, optionally applying a percentage adjustment to all prices. Configuration from the old period (overrides, particular prices, type rules) can be copied to the new one.

POST /v1/scheduling/convenios/{convenio_id}/contracts/{period_id}/reajuste
FieldTypeRequiredDefaultDescription
new_start_datedateYesStart date for the new period
new_end_datedateNonullEnd date (null = open-ended)
cbhpm_table_versionstringNonullNew CBHPM version
cbhpm_percentagedecimalNonullNew CBHPM percentage (0-100)
reajuste_percentdecimalNonullPrice adjustment (-100 to 1000)
reajuste_descriptionstringNonullDescription (e.g. “Annual 2026 - IGPM + 2%“)
copy_overridesbooleanNotrueCopy procedure overrides from previous period
copy_particular_pricesbooleanNotrueCopy particular prices
copy_type_rulesbooleanNotrueCopy appointment type rules
notesstringNonullNotes for the new period
metadataobjectNonullAdditional metadata

Response includes the new period plus a copy summary:

{
"new_period": { "id": "...", "status": "active", "validity_start": "2026-07-01" },
"closed_period_id": "...",
"overrides_copied": 12,
"particular_prices_copied": 5,
"type_rules_copied": 3
}
Terminal window
curl -X POST "https://your-instance.delphos.app/v1/scheduling/convenios/CONVENIO_ID/contracts/PERIOD_ID/reajuste" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"new_start_date": "2026-07-01",
"new_end_date": "2027-06-30",
"cbhpm_table_version": "2025",
"cbhpm_percentage": 75,
"reajuste_percent": 8.5,
"reajuste_description": "Annual 2026 - IGPM + 2%",
"copy_overrides": true,
"copy_particular_prices": true,
"copy_type_rules": true
}'

Snapshots

Retrieve a point-in-time view of a contract period’s complete configuration, including all overrides, particular prices, and type rules.

GET /v1/scheduling/convenios/{convenio_id}/contracts/{period_id}/snapshot

Snapshots are read-only and useful for billing audits and dispute resolution.

Response fields:

FieldTypeDescription
period_idUUIDContract period UUID
convenio_idUUIDParent convenio UUID
event_datedateReference date for the snapshot
snapshot_generated_atdatetimeWhen the snapshot was generated
validity_startdatePeriod validity start date
validity_enddatePeriod validity end date (null if open-ended)
cbhpm_table_versionstringCBHPM table version
cbhpm_percentagedecimalCBHPM percentage
statusstringPeriod status at snapshot time
reajuste_percentdecimalApplied adjustment percentage
overridesarrayAll procedure override records
particular_pricesarrayAll particular price records
type_rulesarrayAll appointment type rule records

Change Log

Every mutation to a contract period or its child records is recorded in an immutable audit log.

GET /v1/scheduling/convenios/{convenio_id}/contracts/{period_id}/changelog

Each entry contains:

FieldTypeDescription
change_typestringcreate, update, activate, reajuste, etc.
change_descriptionstringHuman-readable description
changed_by_user_idUUIDWho made the change
previous_valuesobjectValues before the change
new_valuesobjectValues after the change
affected_tablestringDatabase table affected
affected_record_countintegerNumber of records affected

Contract Lifecycle Automation

DELPHOS automates contract lifecycle management through a processing endpoint that handles auto-expiration and notification generation.

Run lifecycle processing

POST /v1/scheduling/contracts/lifecycle/process

This idempotent endpoint:

  1. Expires contract periods whose validity_end has passed (transitions from active to expired).
  2. Generates notifications for periods approaching expiration (30-day and 7-day warnings).

Response:

{
"expiration": {
"expired_count": 2,
"expired_period_ids": ["...", "..."],
"processed_at": "2026-04-14T10:00:00Z"
},
"notification": {
"notifications_created": 3,
"notifications_by_type": { "expiry_30d": 2, "expiry_7d": 1 },
"processed_at": "2026-04-14T10:00:00Z"
},
"processed_at": "2026-04-14T10:00:00Z"
}

List lifecycle notifications

GET /v1/scheduling/contracts/notifications
ParameterTypeDefaultDescription
convenio_idUUIDnullFilter by convenio
offsetinteger0Pagination offset
limitinteger50Records per page (max 200)

Mark notification as read

PATCH /v1/scheduling/contracts/notifications/{notification_id}/read

Renew an expiring contract

POST /v1/scheduling/convenios/{convenio_id}/contracts/{period_id}/renew

Creates a draft renewal from an existing period, copying all configuration.

FieldTypeRequiredDefaultDescription
new_end_datedateNonullEnd date for renewal (null = open-ended)
cbhpm_table_versionstringNonullOverride CBHPM version (copies from source if null)
cbhpm_percentagefloatNonullOverride percentage (copies from source if null)
notesstringNonullAdministrative notes
metadataobjectNonullStructured metadata

Response includes the new period UUID and a copy summary:

FieldTypeDescription
new_period_idUUIDNewly created draft period
source_period_idUUIDSource period used as template
convenio_idUUIDParent convenio UUID
validity_startdateStart date of the new period
validity_enddateEnd date (null if open-ended)
cbhpm_table_versionstringCBHPM table version of the new period
cbhpm_percentagefloatCBHPM percentage of the new period
overrides_copiedintegerNumber of overrides copied
particular_prices_copiedintegerNumber of prices copied
type_rules_copiedintegerNumber of type rules copied
statusstringAlways "draft"
created_atdatetimeWhen the new period was created

Error Handling

All contract endpoints return structured error responses:

{
"detail": "Contract period not found: a1b2c3d4-..."
}
CodeWhen
404Convenio or period not found
409Overlapping periods or duplicate convenio
422Invalid state transition or validation error
500Internal server error