Create a storage contract on a surface area (automatic position when placement is omitted) or a trailer spot, draft or active (storage.manage)
curl --request POST \ --url https://example.com/api/admin/v1/marinas/example/storage/contracts \ --header 'Content-Type: application/json' \ --header 'X-CSRF-Token: <X-CSRF-Token>' \ --cookie porto_session=<porto_session> \ --data '{ "term": "annual", "customer_id": "example", "billing_customer_id": "example", "vessel_id": "example", "starts_on": "2026-04-15", "ends_on": "2026-04-15", "area_id": "example", "trailer_spot_id": "example", "placement": { "x_cm": 1, "y_cm": 1, "rotation_dd": 0 }, "cradle_resource_id": "example", "support": "cradle", "support_owner": "own", "haul_out_on": "2026-04-15", "launch_on": "2026-04-15", "services": [ { "item_id": "example", "qty_milli": 1 } ], "policy": { "version": 1, "reprice_on_move": true, "release_policy": "never", "allow_segments": true, "payment": { "deposit": { "bp": 1, "cents": 1 }, "deposit_due_days": 1, "schedule": { "mode": "fixed_dates", "dates": [ { "due_on": "example", "bp": 1 } ], "every_months": 1, "count": 1, "first_due_offset_months": 1, "due_offset_days": 1 }, "issue_days_before_due": 1, "rounding_unit_cents": 1, "early_payment": { "discount_bp": 1, "pay_by_offset_days": 1 }, "sepa": true }, "renewal": { "tacit": true, "notice_days": 1 }, "cancellation": { "notice_days": 1, "refund": "pro_rata", "penalty_bp": 1 } }, "notes": "example", "notes_handling": "example", "activate": true, "fit_override": { "reason": "example" } }'409 storage_no_space when no position is free for the period; 422 storage_target_invalid, fit_blocked (support_not_allowed is never overridable).
Authorizations
Sezione intitolata “Authorizations”Parameters
Sezione intitolata “Parameters”Path Parameters
Sezione intitolata “Path Parameters”Header Parameters
Sezione intitolata “Header Parameters”8 to 128 characters of [A-Za-z0-9_-:.]; the response is replayed for 24 hours, 7 days for offline operations (x-porto-offline).
Request Bodyrequired
Sezione intitolata “Request Bodyrequired”Exactly one of area_id (surface dynamic area of a yard or shed map) and trailer_spot_id (land resource of kind trailer_spot). Without placement on an area the optimizer chooses a position (409 storage_no_space when none is free). ends_on defaults by term (annual +1 year, seasonal the season end of the active storage list, monthly +1 month; period requires it).
object
Calendar date YYYY-MM-DD in the marina timezone
Calendar date YYYY-MM-DD in the marina timezone
Top-left corner of the footprint box in area grid space (cm, snapped to cells by the service) and rotation
object
Length in integer centimetres
Length in integer centimetres
Rotation on a surface area in tenths of a degree (multiples of 90°; 0/1800 and 900/2700 are the same rectangle)
Marina cradle (land resource of kind cradle) for the whole period
How the boat stands ashore (fit code support_not_allowed when the area does not accept it)
Calendar date YYYY-MM-DD in the marina timezone
Calendar date YYYY-MM-DD in the marina timezone
object
Versioned contract policy (m3-plan §4.7); unknown keys are rejected
object
V1 rows are read as v2 with the defaults (M4)
object
object
object
MM-DD (rolled into the contract period) or YYYY-MM-DD
object
object
Accept the blocking dimensional fit codes (occupancy.override_fit); the reason is audited
object
Responses
Sezione intitolata “Responses”Created
object
A mooring contract or a transit
object
ORM-2026-0001, TRN-2026-0001
Mooring statuses (draft..suspended) and transit statuses (held..awaiting_approval)
The customer embedded in views; display_name only with customers.read
object
The customer embedded in views; display_name only with customers.read
object
The vessel embedded in occupancy and contract views (no registration, no owner)
object
Length in integer centimetres
Length in integer centimetres
Length in integer centimetres
Calendar date YYYY-MM-DD in the marina timezone
Calendar date YYYY-MM-DD in the marina timezone
Amount in integer cents of the marina currency
Amount in integer cents of the marina currency
object
object
object
Calendar date YYYY-MM-DD in the marina timezone
Exclusive; may be after the departure (best_combination overshoot)
Hour, half_day and day (and week) are accepted only on flat base rules of items with revenue class rental (M11, priced by RentalQuote, ignored by the mooring engine)
object
object
Calendar date YYYY-MM-DD in the marina timezone
Last night (inclusive)
object
object
Trace code (pricing/trace.go), shown as pricingEnums:trace.
object
What the simulator used after resolving ids; never names or contact data.
object
Calendar date YYYY-MM-DD in the marina timezone
Versioned contract policy (m3-plan §4.7); unknown keys are rejected
object
V1 rows are read as v2 with the defaults (M4)
object
object
object
MM-DD (rolled into the contract period) or YYYY-MM-DD
object
object
Local time HH:MM in the marina timezone
Local time HH:MM in the marina timezone
Only with contracts.write or transits.desk
Calendar date YYYY-MM-DD in the marina timezone
Refund (negative) or penalty (positive) from the cancellation policy; charged in M5
object
object
Calendar date YYYY-MM-DD in the marina timezone
Calendar date YYYY-MM-DD in the marina timezone
The open renewal proposal of this contract
object
Quantity in thousandths (1.5 = 1500)
Amount in integer cents of the marina currency
object
Length in integer centimetres
Length in integer centimetres
Angle in tenths of a degree, 0 = +x, 900 = +y (y down, clockwise on screen)
Calendar date YYYY-MM-DD in the marina timezone
Calendar date YYYY-MM-DD in the marina timezone
object
Inclusive range of nights
object
Calendar date YYYY-MM-DD in the marina timezone
Calendar date YYYY-MM-DD in the marina timezone
object
Calendar date YYYY-MM-DD in the marina timezone
Calendar date YYYY-MM-DD in the marina timezone
Amount in integer cents of the marina currency
Only with customers.read
object
The vessel embedded in occupancy and contract views (no registration, no owner)
object
Length in integer centimetres
Length in integer centimetres
Length in integer centimetres
Calendar date YYYY-MM-DD in the marina timezone
Only with customers.read
Exit_on = launch_on or ends_on; arrival_on = haul_out_on or starts_on, clamped into the period
object
How the boat stands ashore (fit code support_not_allowed when the area does not accept it)
Calendar date YYYY-MM-DD in the marina timezone
Calendar date YYYY-MM-DD in the marina timezone
Calendar date YYYY-MM-DD in the marina timezone
Calendar date YYYY-MM-DD in the marina timezone
object
Length in integer centimetres
Length in integer centimetres
Rotation on a surface area in tenths of a degree (multiples of 90°; 0/1800 and 900/2700 are the same rectangle)
Calendar date YYYY-MM-DD in the marina timezone
Calendar date YYYY-MM-DD in the marina timezone
object
Length in integer centimetres
Length in integer centimetres
Rotation on a surface area in tenths of a degree (multiples of 90°; 0/1800 and 900/2700 are the same rectangle)
Calendar date YYYY-MM-DD in the marina timezone
Calendar date YYYY-MM-DD in the marina timezone
object
Percentage in integer basis points (1 % = 100)
object
Length in integer centimetres
Length in integer centimetres
object
Length in integer centimetres
Length in integer centimetres
Example
{ "contract": { "kind": "mooring", "term": "annual", "status": "draft", "vessel": { "hull_type": "monohull_motor" }, "channel": "desk", "breakdown": { "contract_type": "annual", "lines": [ { "kind": "berth", "item_type": "berth_fee", "blocks": [ { "unit": "night" } ] } ], "resolved": { "hull_type": "monohull_motor", "customer_category": "member", "channel": "desk", "dimension_origin": "declared" } }, "policy": { "version": 1, "release_policy": "never", "payment": { "schedule": { "mode": "fixed_dates" }, "rounding_unit_cents": 1 }, "cancellation": { "refund": "pro_rata" } }, "confirmation_source": "manual", "charter": { "pricing_mode": "per_berth" }, "warnings": [ "insurance_missing" ], "lines": [ { "line_kind": "resource", "resource_type": "berth" } ], "allocations": [ { "resource_type": "berth", "kind": "hold", "status": "active" } ], "releases": [ { "resource_type": "berth", "status": "active", "source": "customer_phone" } ], "presences": [ { "vessel": { "hull_type": "monohull_motor" }, "event": "arrived", "source": "staff" } ] }, "details": { "support": "cradle", "support_owner": "own" }, "placement": { "resource_type": "berth", "rotation_dd": 0 }, "cradle": { "resource_type": "berth", "rotation_dd": 0 }, "fit": { "blocking": [ { "code": "loa_exceeds" } ], "warnings": [ { "code": "loa_exceeds" } ] }}Headers
Sezione intitolata “Headers”Version of the resource, quoted (“3”)
Malformed request or validation failure
object
object
Map validation issues (map_invalid)
object
ValidateMap rule (m1-plan §2.3), e.g. berth_overlap
Numbers only (cm, counts)
object
Price list validation issues (price_list_invalid)
object
Pricing.Validate issue code (m2-plan §4.8), e.g. period_overlap
object
Id of the row, or the client key of an unsaved one
Codes and integers as strings; never personal data
object
Machine-readable details: no_price {item_id, contract_type, night, unit, category, band, reason}; price_list_overlap {conflicts: [{id, code, valid_from, valid_to}]}; in_use {references}; resource_taken ConflictDetail; fit_blocked FitResult; placement_invalid {reason, allocation_id?}; invalid_transition {from, action}; closure_active {closure_id, from_date, to_date}; release_invalid {reason}; allocation_changed {current_resource_id, current_resource_code} (null when the allocation is gone); remote_pin_mismatch {expected_fingerprint, presented_fingerprint}; scenario_conflicts {conflicts: [StorageScenarioConflict]}; maintenance_conflicts {conflicts: [MaintenanceConflict]}; storage_no_space {area_id, from, to}. Ids, codes, dates and integers only.
object
Example
{ "type": "bad_request", "issues": [ { "severity": "error" } ], "price_list_issues": [ { "severity": "error", "ref": { "kind": "list" } } ]}Not authenticated, or invalid credentials
object
object
Map validation issues (map_invalid)
object
ValidateMap rule (m1-plan §2.3), e.g. berth_overlap
Numbers only (cm, counts)
object
Price list validation issues (price_list_invalid)
object
Pricing.Validate issue code (m2-plan §4.8), e.g. period_overlap
object
Id of the row, or the client key of an unsaved one
Codes and integers as strings; never personal data
object
Machine-readable details: no_price {item_id, contract_type, night, unit, category, band, reason}; price_list_overlap {conflicts: [{id, code, valid_from, valid_to}]}; in_use {references}; resource_taken ConflictDetail; fit_blocked FitResult; placement_invalid {reason, allocation_id?}; invalid_transition {from, action}; closure_active {closure_id, from_date, to_date}; release_invalid {reason}; allocation_changed {current_resource_id, current_resource_code} (null when the allocation is gone); remote_pin_mismatch {expected_fingerprint, presented_fingerprint}; scenario_conflicts {conflicts: [StorageScenarioConflict]}; maintenance_conflicts {conflicts: [MaintenanceConflict]}; storage_no_space {area_id, from, to}. Ids, codes, dates and integers only.
object
Example
{ "type": "bad_request", "issues": [ { "severity": "error" } ], "price_list_issues": [ { "severity": "error", "ref": { "kind": "list" } } ]}Authenticated but not allowed
object
object
Map validation issues (map_invalid)
object
ValidateMap rule (m1-plan §2.3), e.g. berth_overlap
Numbers only (cm, counts)
object
Price list validation issues (price_list_invalid)
object
Pricing.Validate issue code (m2-plan §4.8), e.g. period_overlap
object
Id of the row, or the client key of an unsaved one
Codes and integers as strings; never personal data
object
Machine-readable details: no_price {item_id, contract_type, night, unit, category, band, reason}; price_list_overlap {conflicts: [{id, code, valid_from, valid_to}]}; in_use {references}; resource_taken ConflictDetail; fit_blocked FitResult; placement_invalid {reason, allocation_id?}; invalid_transition {from, action}; closure_active {closure_id, from_date, to_date}; release_invalid {reason}; allocation_changed {current_resource_id, current_resource_code} (null when the allocation is gone); remote_pin_mismatch {expected_fingerprint, presented_fingerprint}; scenario_conflicts {conflicts: [StorageScenarioConflict]}; maintenance_conflicts {conflicts: [MaintenanceConflict]}; storage_no_space {area_id, from, to}. Ids, codes, dates and integers only.
object
Example
{ "type": "bad_request", "issues": [ { "severity": "error" } ], "price_list_issues": [ { "severity": "error", "ref": { "kind": "list" } } ]}Not found (or not visible to the principal)
object
object
Map validation issues (map_invalid)
object
ValidateMap rule (m1-plan §2.3), e.g. berth_overlap
Numbers only (cm, counts)
object
Price list validation issues (price_list_invalid)
object
Pricing.Validate issue code (m2-plan §4.8), e.g. period_overlap
object
Id of the row, or the client key of an unsaved one
Codes and integers as strings; never personal data
object
Machine-readable details: no_price {item_id, contract_type, night, unit, category, band, reason}; price_list_overlap {conflicts: [{id, code, valid_from, valid_to}]}; in_use {references}; resource_taken ConflictDetail; fit_blocked FitResult; placement_invalid {reason, allocation_id?}; invalid_transition {from, action}; closure_active {closure_id, from_date, to_date}; release_invalid {reason}; allocation_changed {current_resource_id, current_resource_code} (null when the allocation is gone); remote_pin_mismatch {expected_fingerprint, presented_fingerprint}; scenario_conflicts {conflicts: [StorageScenarioConflict]}; maintenance_conflicts {conflicts: [MaintenanceConflict]}; storage_no_space {area_id, from, to}. Ids, codes, dates and integers only.
object
Example
{ "type": "bad_request", "issues": [ { "severity": "error" } ], "price_list_issues": [ { "severity": "error", "ref": { "kind": "list" } } ]}Conflict with the current state
object
object
Map validation issues (map_invalid)
object
ValidateMap rule (m1-plan §2.3), e.g. berth_overlap
Numbers only (cm, counts)
object
Price list validation issues (price_list_invalid)
object
Pricing.Validate issue code (m2-plan §4.8), e.g. period_overlap
object
Id of the row, or the client key of an unsaved one
Codes and integers as strings; never personal data
object
Machine-readable details: no_price {item_id, contract_type, night, unit, category, band, reason}; price_list_overlap {conflicts: [{id, code, valid_from, valid_to}]}; in_use {references}; resource_taken ConflictDetail; fit_blocked FitResult; placement_invalid {reason, allocation_id?}; invalid_transition {from, action}; closure_active {closure_id, from_date, to_date}; release_invalid {reason}; allocation_changed {current_resource_id, current_resource_code} (null when the allocation is gone); remote_pin_mismatch {expected_fingerprint, presented_fingerprint}; scenario_conflicts {conflicts: [StorageScenarioConflict]}; maintenance_conflicts {conflicts: [MaintenanceConflict]}; storage_no_space {area_id, from, to}. Ids, codes, dates and integers only.
object
Example
{ "type": "bad_request", "issues": [ { "severity": "error" } ], "price_list_issues": [ { "severity": "error", "ref": { "kind": "list" } } ]}The vessel does not fit (fit_blocked, with the FitResult in details), the placement is invalid (placement_invalid, details {reason, allocation_id?}), a customer is required (customer_required), no price (no_price), a validation failure, or an idempotency key was reused
object
object
Map validation issues (map_invalid)
object
ValidateMap rule (m1-plan §2.3), e.g. berth_overlap
Numbers only (cm, counts)
object
Price list validation issues (price_list_invalid)
object
Pricing.Validate issue code (m2-plan §4.8), e.g. period_overlap
object
Id of the row, or the client key of an unsaved one
Codes and integers as strings; never personal data
object
Machine-readable details: no_price {item_id, contract_type, night, unit, category, band, reason}; price_list_overlap {conflicts: [{id, code, valid_from, valid_to}]}; in_use {references}; resource_taken ConflictDetail; fit_blocked FitResult; placement_invalid {reason, allocation_id?}; invalid_transition {from, action}; closure_active {closure_id, from_date, to_date}; release_invalid {reason}; allocation_changed {current_resource_id, current_resource_code} (null when the allocation is gone); remote_pin_mismatch {expected_fingerprint, presented_fingerprint}; scenario_conflicts {conflicts: [StorageScenarioConflict]}; maintenance_conflicts {conflicts: [MaintenanceConflict]}; storage_no_space {area_id, from, to}. Ids, codes, dates and integers only.
object
Example
{ "type": "bad_request", "issues": [ { "severity": "error" } ], "price_list_issues": [ { "severity": "error", "ref": { "kind": "list" } } ]}Porto è sviluppato da Coste360 SRL. Codice sorgente disponibile con licenza BSL 1.1; il marchio Porto è escluso dalla licenza.