Документація API

Інтеграція біржі SAMO-TRANS у вашу TMS або CRM

Документація API

Довідник ендпоінтів

Усі методи публічного API: шляхи, параметри, схеми запитів і коди відповідей.

Базова адреса

https://api.samo-trans.com/api/public/v1

Інтерактивна консоль зі схемами запитів доступна у Swagger UI на боці API.

Public · Reference

GET/reference/countriesreference:read

List countries served by the exchange

Параметри

localequerystringLocale for display names (default "ua")

* обовʼязкове поле

Відповіді

  • 200
GET/reference/regionsreference:read

List regions/oblasts for a country

Параметри

country*querystringISO 3166-1 alpha-2 country code
localequerystringLocale for display names (default "ua")

* обовʼязкове поле

Відповіді

  • 200
GET/reference/car-typesreference:read

Car body types (grouped) — valid `carTypes` codes for a proposal

Параметри

Параметрів немає

Відповіді

  • 200
GET/reference/vehicle-typesreference:read

Vehicle composition types — valid optional `vehicleType` codes

Параметри

Параметрів немає

Відповіді

  • 200
GET/reference/load-typesreference:read

Loading/unloading types — valid `loadUnloadTypes` codes

Параметри

Параметрів немає

Відповіді

  • 200
GET/reference/permitsreference:read

Transport permit/document types — valid `carPermits` codes

Параметри

Параметрів немає

Відповіді

  • 200
GET/reference/currenciesreference:read

Supported currencies — valid `currencyType` values

Параметри

Параметрів немає

Відповіді

  • 200
GET/reference/payment-typesreference:read

Payment forms — valid `paymentType` values

Параметри

Параметрів немає

Відповіді

  • 200

Public · Localities

Public · My proposals

POST/proposals/cargoproposals:write

Create a CARGO proposal

companyId is always resolved from the API key — never from the request body. type is fixed by this route. contactPersonId is optional: if given, it must be the company owner or an ACTIVE employee of the key's company; if omitted, it defaults to the key's owner.

Параметри

Параметрів немає

Тіло запиту

PublicCreateProposalDto(обовʼязковий)

Відповіді

  • 201Proposal created
POST/proposals/transportproposals:write

Create a TRANSPORT proposal

companyId is always resolved from the API key — never from the request body. type is fixed by this route. contactPersonId is optional: if given, it must be the company owner or an ACTIVE employee of the key's company; if omitted, it defaults to the key's owner.

Параметри

Параметрів немає

Тіло запиту

PublicCreateProposalDto(обовʼязковий)

Відповіді

  • 201Proposal created
POST/proposals/batchproposals:write

Create up to 25 proposals in one request

Each item is validated and created independently — the response carries a per-item result ({index, status:"created", proposal} or {index, status:"error", error}). The whole batch consumes N of the daily write quota (not 1); if it would exceed the quota the request is rejected with 429 before creating anything. Combine with an Idempotency-Key for safe retries.

Параметри

Параметрів немає

Тіло запиту

PublicBatchCreateDto(обовʼязковий)

Відповіді

  • 200Per-item batch result
GET/proposals/myproposals:read

List the calling key’s own proposals

Scoped via ProposalsService.getMyProposals — never leaks other companies’ proposals.

Параметри

typequery"TRANSPORT" | "CARGO"Filter by proposal type
statusquery"ACTIVE" | "INACTIVE"Filter by status
limitquerynumberMax rows to return (default 20, capped at 100)
cursorquerystringOpaque pagination cursor returned as `nextCursor` from a previous page
sortByquery"createdAt" | "viewCount"Sort field (default createdAt)
sortOrderquery"asc" | "desc"Sort order (default desc)

* обовʼязкове поле

Відповіді

  • 200Page of the key’s own proposals
PATCH/proposals/{id}proposals:write

Update a proposal

Параметри

id*pathstringProposal id

* обовʼязкове поле

Тіло запиту

PublicUpdateProposalDto(обовʼязковий)

Відповіді

  • 200Proposal updated
DELETE/proposals/{id}proposals:write

Delete a proposal permanently

Параметри

id*pathstringProposal id

* обовʼязкове поле

Відповіді

  • 200Proposal deleted
POST/proposals/{id}/bumpproposals:write

Bump a proposal to the top of search results

Ownership matches update/delete/archive: the proposal’s author, its contact person, or an owner/manager of the owning company may bump it. May fail with BUMP_NOT_OWNER, BUMP_TOO_SOON, or BUMP_LIMIT_REACHED. These are internal { code, message } exceptions, not public-API error codes — PublicApiExceptionFilter remaps them onto the stable public set: BUMP_NOT_OWNER (ForbiddenException) becomes 403 { error: { code: 'forbidden' } }; BUMP_TOO_SOON and BUMP_LIMIT_REACHED (both BadRequestException) become 400 { error: { code: 'validation_error' } }. The specific reason is always preserved in the envelope’s `message`, never in `code`.

Параметри

id*pathstringProposal id

* обовʼязкове поле

Відповіді

  • 200Proposal bumped
POST/proposals/{id}/archiveproposals:write

Archive (deactivate) a proposal — idempotent

There is no dedicated archive() in ProposalsService, only toggleStatus() which flips ACTIVE⇄INACTIVE. This route calls ProposalsService.setProposalStatus(id, actorUserId, 'INACTIVE'), which verifies ownership FIRST and only then no-ops if the proposal is already INACTIVE — so a key with no rights over the proposal gets 403 even when it is already in the target state, instead of silently succeeding.

Параметри

id*pathstringProposal id

* обовʼязкове поле

Відповіді

  • 200Proposal is INACTIVE (already was, or just deactivated)
POST/proposals/{id}/restoreproposals:write

Restore (reactivate) a proposal — idempotent

Mirror of /archive: calls ProposalsService.setProposalStatus(id, actorUserId, 'ACTIVE'), which verifies ownership FIRST and only then no-ops if already ACTIVE. Reactivating is a real ProposalsService side effect — it RESETS createdAt and viewCount to 0 (proposals.service.ts toggleStatus/setProposalStatus), the same behavior the web app has today. Bringing a proposal back online consumes an active-proposal slot from the company plan exactly as creating one does, so this returns 400 when the company is at its maxActiveProposals cap. The already-ACTIVE no-op never consumes a slot and stays 200 even at the cap.

Параметри

id*pathstringProposal id

* обовʼязкове поле

Відповіді

  • 200Proposal is ACTIVE (already was, or just reactivated)
GET/proposals/{id}proposals:read

Get a single proposal by id

Параметри

id*pathstringProposal id
localequerystringLocale for display names (default "ua")

* обовʼязкове поле

Відповіді

  • 200The matching proposal

Public · Companies

GET/companies/{id}reference:read

Get a company profile (name, legal form, rating + reviews summary, contacts)

Параметри

id*pathstringCompany id

* обовʼязкове поле

Відповіді

  • 200
GET/companies/{id}/reviewsreference:read

Paginated APPROVED reviews of a company (counterparty reputation)

Параметри

id*pathstringCompany id
pagequerystringPage (default 1)
limitquerystringPage size (default 10, capped at 50)

* обовʼязкове поле

Відповіді

  • 200

Public · Employees

GET/employeesemployees:read

List the key's company staff

Returns every membership of the company the key belongs to, including PENDING invitations. Use `userId` (not `id`) as a proposal `contactPersonId`.

Параметри

Параметрів немає

Відповіді

  • 200Company staff
GET/employees/{id}/proposals-countemployees:read

Count the listings an employee is contact person for

Useful before deactivating someone — those listings keep pointing at them.

Параметри

id*pathstringMembership id (the `id` field of an employee)

* обовʼязкове поле

Відповіді

  • 200Listing count
PATCH/employees/{id}/statusemployees:write

Activate or deactivate an employee

DEACTIVATED removes the person's access to the company dashboard — they land on the suspended screen — but only if they have no other ACTIVE employment; it does not block signing in to the platform and does not end an existing session. Their listings stay published and keep pointing at them as contact person — check /employees/{id}/proposals-count first. Idempotent: setting the status an employee already has succeeds and changes nothing.

Параметри

id*pathstringMembership id

* обовʼязкове поле

Тіло запиту

SetEmployeeStatusDto(обовʼязковий)

Відповіді

  • 200Updated employee
PATCH/employees/{id}employees:write

Change an employee's role or display name

The OWNER role cannot be assigned — ownership is not transferable through this API.

Параметри

id*pathstringMembership id

* обовʼязкове поле

Тіло запиту

UpdateEmployeeDto(обовʼязковий)

Відповіді

  • 200Updated employee

Схеми

ProposalLocationInput
type*"locality" | "region" | "country"Location type: locality, region, or country
osmIdstringOSM ID for locality
regionCodestringRegion code (e.g., UA-59)
countryCodestringCountry code (e.g., UA)

* обовʼязкове поле

PublicCreateProposalDto
startLocations*ProposalLocationInput[]Start locations (multiple allowed)
endLocations*ProposalLocationInput[]End locations (multiple allowed)
dataLoadStart*stringDate when loading starts
dataLoadEnd*stringDate when loading ends
capacity*numberCapacity in tons
volumenumberVolume in m3
description*stringDescription of the proposal. Phone numbers, e-mail addresses, @handles and links are removed from the text before it is stored (contacts stay behind the platform paywall). This never fails the request — the listing is saved with the cleaned text, so the value returned by a later GET may be shorter than the one you sent.
pricenumberPrice value
currencyType"USD" | "EUR" | "UAH" | "PLN"
paymentType"CASH" | "CASHLESS" | "MIXED"
priceVatbooleanPrice includes VAT
priceRequestbooleanRequest price
priceForstringPrice for (per_km, per_ton, etc)
lengthnumber
widthnumber
heightnumber
temperatureMinnumberLower bound of the required temperature range, °C. Only allowed when `carTypes` contains a temperature-controlled body (`ref`, `ref-tushe`, `izoterm`) — otherwise the request is rejected with 400 rather than silently ignored. Either bound may be omitted: "up to +2" and "from -18" are both valid.
temperatureMaxnumberUpper bound of the required temperature range, °C. Must not be lower than `temperatureMin`. See `temperatureMin` for the car-type rule.
carTypes*string[]Car body type codes (see GET /reference/car-types)
loadUnloadTypesstring[]
carPermitsstring[]
vehicleTypeobjectOptional vehicle composition code (see GET /reference/vehicle-types). Independent from carTypes and only valid for TRANSPORT proposals.
separateCarboolean
carNumbernumber
shipperRolestring
addLoadboolean
addLoadPossibleboolean
contactPersonIdstringContact Person ID (optional, defaults to user)
fleetVehicleIdobjectFleet vehicle this TRANSPORT proposal publishes (null to unlink)

* обовʼязкове поле

PublicBatchProposalItemDto
startLocations*ProposalLocationInput[]Start locations (multiple allowed)
endLocations*ProposalLocationInput[]End locations (multiple allowed)
dataLoadStart*stringDate when loading starts
dataLoadEnd*stringDate when loading ends
capacity*numberCapacity in tons
volumenumberVolume in m3
description*stringDescription of the proposal. Phone numbers, e-mail addresses, @handles and links are removed from the text before it is stored (contacts stay behind the platform paywall). This never fails the request — the listing is saved with the cleaned text, so the value returned by a later GET may be shorter than the one you sent.
pricenumberPrice value
currencyType"USD" | "EUR" | "UAH" | "PLN"
paymentType"CASH" | "CASHLESS" | "MIXED"
priceVatbooleanPrice includes VAT
priceRequestbooleanRequest price
priceForstringPrice for (per_km, per_ton, etc)
lengthnumber
widthnumber
heightnumber
temperatureMinnumberLower bound of the required temperature range, °C. Only allowed when `carTypes` contains a temperature-controlled body (`ref`, `ref-tushe`, `izoterm`) — otherwise the request is rejected with 400 rather than silently ignored. Either bound may be omitted: "up to +2" and "from -18" are both valid.
temperatureMaxnumberUpper bound of the required temperature range, °C. Must not be lower than `temperatureMin`. See `temperatureMin` for the car-type rule.
carTypes*string[]Car body type codes (see GET /reference/car-types)
loadUnloadTypesstring[]
carPermitsstring[]
vehicleTypeobjectOptional vehicle composition code (see GET /reference/vehicle-types). Independent from carTypes and only valid for TRANSPORT proposals.
separateCarboolean
carNumbernumber
shipperRolestring
addLoadboolean
addLoadPossibleboolean
contactPersonIdstringContact Person ID (optional, defaults to user)
fleetVehicleIdobjectFleet vehicle this TRANSPORT proposal publishes (null to unlink)
type*"TRANSPORT" | "CARGO"CARGO or TRANSPORT

* обовʼязкове поле

PublicBatchCreateDto
items*PublicBatchProposalItemDto[]Between 1 and 25 proposals to create in one request.

* обовʼязкове поле

PublicUpdateProposalDto
startLocationsProposalLocationInput[]Start locations (multiple allowed)
endLocationsProposalLocationInput[]End locations (multiple allowed)
dataLoadStartstringDate when loading starts
dataLoadEndstringDate when loading ends
capacitynumberCapacity in tons
volumenumberVolume in m3
descriptionstringDescription of the proposal. Phone numbers, e-mail addresses, @handles and links are removed from the text before it is stored (contacts stay behind the platform paywall). This never fails the request — the listing is saved with the cleaned text, so the value returned by a later GET may be shorter than the one you sent.
pricenumberPrice value
currencyType"USD" | "EUR" | "UAH" | "PLN"
paymentType"CASH" | "CASHLESS" | "MIXED"
priceVatbooleanPrice includes VAT
priceRequestbooleanRequest price
priceForstringPrice for (per_km, per_ton, etc)
lengthnumber
widthnumber
heightnumber
temperatureMinnumberLower bound of the required temperature range, °C. Only allowed when `carTypes` contains a temperature-controlled body (`ref`, `ref-tushe`, `izoterm`) — otherwise the request is rejected with 400 rather than silently ignored. Either bound may be omitted: "up to +2" and "from -18" are both valid.
temperatureMaxnumberUpper bound of the required temperature range, °C. Must not be lower than `temperatureMin`. See `temperatureMin` for the car-type rule.
carTypesstring[]Car body type codes (see GET /reference/car-types)
loadUnloadTypesstring[]
carPermitsstring[]
vehicleTypeobjectOptional vehicle composition code (see GET /reference/vehicle-types). Independent from carTypes and only valid for TRANSPORT proposals.
separateCarboolean
carNumbernumber
shipperRolestring
addLoadboolean
addLoadPossibleboolean
contactPersonIdstringContact Person ID (optional, defaults to user)
fleetVehicleIdobjectFleet vehicle this TRANSPORT proposal publishes (null to unlink)
versionnumberCurrent version for optimistic locking

* обовʼязкове поле

SetEmployeeStatusDto
status*"ACTIVE" | "DEACTIVATED"ACTIVE = grant access; DEACTIVATED = remove access to the company dashboard (only when the person has no other ACTIVE employment) — it does not block signing in to the platform.

* обовʼязкове поле

UpdateEmployeeDto
role"MANAGER" | "DRIVER" | "ACCOUNTANT" | "DISPATCHER"
namestring

* обовʼязкове поле