Skip to content

Endpoints

All endpoints are prefixed with https://api-rest.tendios.com/api and require the api-key header.


Context

Get caller context

http
GET /v1/whoami

Returns who the calling API key belongs to. Useful as a first call to confirm a key is wired up correctly and to discover the account and organization it resolves to — you never pass an account id to the other endpoints, so this is how you find out which account you're acting on.

Response

FieldTypeDescription
principal.typestringAlways apiKey
principal.idstringID of the key making the call
principal.namestringThe name you gave the key, e.g. Claude integration
account.idstringAccount the key belongs to
account.namestringAccount name
account.slugstringAccount slug
organizationobject | null{ id, name } of the linked organization, if any
plan.tierstring | nullActive Bid plan tier, e.g. tier_2

Example

bash
curl https://api-rest.tendios.com/api/v1/whoami \
  -H "api-key: tend_your_key"

Tenders

Search tenders

http
POST /v1/tenders/search

Returns a paginated list of tenders matching the given filters.

Request body

FieldTypeDescription
textstringFree-text search query
pagenumberPage number (default: 1)
pageSizenumberResults per page (max 100, default: 20)
sortstringby-published-date | by-submission-date | by-budget
isDescendentbooleanSort descending (default: true)
statusstring[]Filter by status values
locationsstring[]Location filters e.g. ["country/ES", "province/28"]
minBudgetnumberMinimum budget (no taxes)
maxBudgetnumberMaximum budget (no taxes)

Example

bash
curl -X POST https://api-rest.tendios.com/api/v1/tenders/search \
  -H "api-key: tend_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "text": "IT services", "pageSize": 10, "locations": ["country/ES"] }'

Response — see Pagination for the envelope shape.


Get tender by ID

http
GET /v1/tenders/{id}

Returns the full detail of a single tender.

Path params

ParamDescription
idTender ID (e.g. 507f1f77bcf86cd799439011)

Example

bash
curl https://api-rest.tendios.com/api/v1/tenders/507f1f77bcf86cd799439011 \
  -H "api-key: tend_your_key"

Get tender sheets

http
GET /v1/tenders/{id}/sheets

Returns all document sheets attached to a tender.

Path params

ParamDescription
idTender ID

Download tender sheet

http
GET /v1/tenders/sheets/{sheetId}/download

Downloads a single tender document file.

Path params

ParamDescription
sheetIdSheet ID

http
GET /v1/tenders/documents/{token}/download

Downloads a tender document using a short-lived, pre-signed token instead of a sheet id. This is the form the MCP get_tender_sheets tool hands back, so an assistant can surface a working download link without streaming bytes through a tool result.

Path params

ParamDescription
tokenShort-lived token identifying the file

Organizations

Get organization profile

http
GET /v1/organizations/{idOrSlug}

Returns the public profile of an organization (bidder or contracting body).

Path params

ParamDescription
idOrSlugOrganization id (e.g. the contractingOrganizationId of a tender) or slug (e.g. altia-consultores-sa). Both resolve the same organization and response

Response fields

FieldTypeDescription
idstringOrganization ID
namestringOrganization name
typestringbidder or public-contracting-institution
taxIdstring?Tax identification number
activitystring?Business activity description
countrystring?ISO 3166-1 alpha-2 country code
addressobject?{ city, province, postCode, street }
webUrlstring?Website URL
logostring?Logo image URL

Example

bash
# By slug
curl https://api-rest.tendios.com/api/v1/organizations/altia-consultores-sa \
  -H "api-key: tend_your_key"

# By id — e.g. the contractingOrganizationId returned by the tender endpoints
curl https://api-rest.tendios.com/api/v1/organizations/507f1f77bcf86cd799439012 \
  -H "api-key: tend_your_key"

Get organization award statistics

http
GET /v1/organizations/{idOrSlug}/awards

Returns yearly award statistics and sector breakdown for an organization.

Path params

ParamDescription
idOrSlugOrganization id (e.g. the contractingOrganizationId of a tender) or slug, same as the above

Response fields

FieldTypeDescription
organizationIdstringOrganization ID
organizationNamestringOrganization name
typestringbidder or public-contracting-institution
statsarrayYearly stats: [{ year, count, totalAmount }]
sectorsarrayCPV sector breakdown: [{ divisionCode, divisionNameEn, divisionNameEs, emoji, count, percentage }]

Example

bash
curl https://api-rest.tendios.com/api/v1/organizations/altia-consultores-sa/awards \
  -H "api-key: tend_your_key"

# Or by id
curl https://api-rest.tendios.com/api/v1/organizations/507f1f77bcf86cd799439012/awards \
  -H "api-key: tend_your_key"

CPV codes

Get CPV details

http
GET /v1/cpv/{code}

Returns details for a CPV code including names in 7 EU languages.

Path params

ParamDescription
codeCPV code (e.g. 72000000)

Response fields

FieldTypeDescription
codestringCPV code
typestringdivision | group | class | category
nameEnstring?Name in English
nameEsstring?Name in Spanish
nameFrstring?Name in French
nameDestring?Name in German
nameItstring?Name in Italian
nameCastring?Name in Catalan
namePtstring?Name in Portuguese
emojistring?Emoji representing the category
fontAwesomeIconstring?Font Awesome icon name

Example

bash
curl https://api-rest.tendios.com/api/v1/cpv/72000000 \
  -H "api-key: tend_your_key"

Alerts

Alerts belong to the account that owns the API key. You never pass an account id — it is resolved from the key.

List alerts

http
GET /v1/alerts

Returns a paginated list of every alert configured for the account, with a total count.

Query params

ParamTypeDefaultDescription
textstringFilter alerts by title
isArchivedbooleanFilter archived or non-archived
pagenumber1Page number
pageSizenumber20Alerts per page (max 100)
sortstringby-update-dateSee alert sort values
sortDirectionstringdescasc or desc

Get an alert

http
GET /v1/alerts/{alertId}

Returns the full configuration of one alert.

Path params

ParamDescription
alertIdAlert ID

Response

FieldTypeDescription
idstringAlert ID
titlestringAlert title
descriptionstring?Optional description
platformUrlstringURL to open the alert in Bid
criteriaobjectTender matching criteria (see below)
notificationConfigobjectSchedule and delivery configuration
responsiblesobject[]Users responsible for the alert
isActivebooleanWhether the alert is running
isPublicbooleanWhether all account users can access it
isArchivedbooleanWhether the alert is archived
isAutoConfiguredbooleanWhether Tendios generated the configuration
createdBystringID of the creator
createdAtdate-timeCreation timestamp
updatedAtdate-timeLast update timestamp
lastNotifiedAtdate-timeLast time the alert matched
lastNotificationSentAtdate-time?Last time an email went out

Create an alert

http
POST /v1/alerts

Creates an alert and returns it. Responds 201.

Request body

FieldTypeRequiredDescription
titlestringYesAlert title
windowsSearchobject[]YesEvents that trigger the alert (min 1) — see below
descriptionstringNoFree-text description
criteriaobjectNoTender matching criteria — see below
notificationConfigobjectNoSchedule and delivery — see below
responsiblesobject[]No{ id, receiveEmails } per recipient
isActivebooleanNoStart active (default true)
isPublicbooleanNoVisible to all account users (default true)

windowsSearch[] — which tender event the alert watches:

FieldTypeDescription
fieldstringexpedientPublishedAt, expedientAdjudicationDate, or expedientExpirationDate
expirationOffsetnumberDays before expiry to notify — only for expedientExpirationDate (min 1)
withExtensionbooleanUse the extended deadline — only for expedientExpirationDate

criteria — every field optional:

FieldTypeDescription
keywordsobject{ include: string[], exclude: string[] }
cpvCodesobject{ include: string[], exclude: string[] }
locationsobject{ country: {include,exclude}, province: {include,exclude} }
budgetobject{ min, max }
statusesstring[]Tender status values, e.g. ["Publicada"] (min 1 when present)
contractTypesstring[]Contract type values
proceduresstring[]Procedure type values
inDeadlinebooleanOnly tenders still open for submission

notificationConfig — every field optional:

FieldTypeDescription
frequencyobject{ type: "daily", weekdays: number[] } or { type: "weekly", dayOfWeek: number } — 1 = Monday, 7 = Sunday
hournumberDelivery hour, 023
timezonestringIANA zone, e.g. Europe/Madrid
attachmentsobject{ hasPdf, hasCsv, hasXlsx }
includeModificationsbooleanInclude modified tenders, not just new ones
sendWithoutItemsbooleanSend the email even when nothing matched

Example

bash
curl -X POST https://api-rest.tendios.com/api/v1/alerts \
  -H "api-key: tend_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "IT services in Madrid",
    "windowsSearch": [{ "field": "expedientPublishedAt" }],
    "criteria": {
      "keywords": { "include": ["software"] },
      "locations": { "province": { "include": ["28"] } },
      "budget": { "min": 50000 }
    },
    "notificationConfig": {
      "frequency": { "type": "daily", "weekdays": [1, 2, 3, 4, 5] },
      "hour": 8,
      "timezone": "Europe/Madrid"
    }
  }'

Update an alert

http
PATCH /v1/alerts/{alertId}

Updates selected fields and returns the alert. Responds 200. Every field is optional — omitted fields are left unchanged.

Path params

ParamDescription
alertIdAlert ID

Request body — the same fields as Create an alert, all optional, plus:

FieldTypeDescription
isArchivedbooleanArchive or unarchive

Get alert tender results

http
POST /v1/alerts/{alertId}/results

Returns tenders that match a saved alert.

Path params

ParamDescription
alertIdAlert ID

Alert sort values

Accepted by sort on List alerts. Default by-update-date.

ValueSorts by
by-nameAlert title
by-update-dateLast update date
by-creation-dateCreation date
by-last-notified-dateLast time the alert matched
by-last-notification-sent-dateLast time an email was sent
by-statusActive/inactive state

Pipelines

List pipelines

http
GET /v1/pipelines

Returns the opportunity pipelines configured for the account, each with its stages. Call this first to get the pipelineId and statusId values the Kanban and Opportunities endpoints need.

Query params

ParamTypeDefaultDescription
pagenumber1Page number
pageSizenumber20Pipelines per page (max 100)

Response — paginated list of:

FieldTypeDescription
idstringPipeline ID
namestringPipeline name
statusesobject[]Stages — see below

statuses[]

FieldTypeDescription
idstringStage ID
namestringStage name
isInitialbooleanWhether new opportunities land here
isTerminalbooleanWhether reaching this stage closes the opportunity
outcomeTypestringOutcome the stage represents
sortPointsnumberBoard ordering weight
showInKanbanbooleanWhether the stage renders as a column
descriptionstring?Optional stage description

Kanban

These endpoints expose the CRM pipeline kanban board. They require the API key of the account that owns the pipeline.

Get pipeline status totals

http
GET /v1/kanban/{pipelineId}/status

Returns opportunity counts and total amounts grouped by pipeline status — used to render kanban column headers.

Path params

ParamDescription
pipelineIdPipeline ID

Query params

ParamTypeDescription
responsiblestring[]Filter by responsible user IDs
teamResponsiblestring[]Filter by responsible team IDs

Response — array of:

FieldTypeDescription
statusobject{ id, name, isInitial, isTerminal, pipelineId, outcomeType, sortPoints, showInKanban, backgroundColor?, textColor?, description? }
opportunityCountnumberNumber of opportunities in this status
totalAmountnumberSum of opportunity amounts
currencystringCurrency code (e.g. EUR)

Get opportunities by status

http
GET /v1/kanban/{pipelineId}/status/{statusId}/opportunities

Returns paginated opportunities for a single kanban column.

Path params

ParamDescription
pipelineIdPipeline ID
statusIdPipeline status ID

Query params

ParamTypeDefaultDescription
pagenumber1Page number
pageSizenumber10Results per page
sortstringSort order

Search kanban opportunities

http
GET /v1/kanban/{pipelineId}/search

Searches opportunities across all statuses in a pipeline. Returns a map of statusId → opportunities[].

Path params

ParamDescription
pipelineIdPipeline ID

Query params

ParamTypeDefaultDescription
searchstringText search term
limitnumber10Max opportunities per status (max 50)
responsiblestring[]Filter by responsible user IDs
teamResponsiblestring[]Filter by responsible team IDs
sortstringSort order

Opportunities

These endpoints act on individual opportunities in the account's CRM pipeline. Get the IDs they need from List pipelines and the Kanban endpoints.

Move an opportunity to another status

http
PUT /v1/opportunities/{opportunityId}/status

Moves an opportunity to a different stage of its current pipeline. Responds 204 — including when the opportunity is already in the requested stage, which makes the call safe to retry.

Path params

ParamDescription
opportunityIdOpportunity ID

Request body

FieldTypeRequiredDescription
targetStatusIduuidYesTarget pipeline stage ID

Moving to a terminal stage closes the opportunity

Stages with isTerminal: true (see List pipelines) end the opportunity's lifecycle. There is no undo through the API — check isTerminal before moving if that isn't what you intend.

Errors403 if the opportunity belongs to another account, 404 if the opportunity or stage doesn't exist.


Get workflow actions

http
GET /v1/opportunities/{opportunityId}/workflow-actions

Returns the current workflow action records for an opportunity, grouped by workflow step. Use it to see which qualification steps have been completed and which are outstanding.

Path params

ParamDescription
opportunityIdOpportunity ID

Response — array of:

FieldTypeDescription
idstringAction ID
workflowStepIdstringStep the action belongs to
workflowStepNamestring?Step name
workflowStepPositionnumber?Step position in the workflow
namestringAction name
targetTypestringWhat the action targets
targetIdstring?ID of the target, when applicable
statusstringAction status
positionnumberPosition within the step
completedAtdate-time?When it was completed
createdAtdate-timeCreation timestamp
updatedAtdate-timeLast update timestamp

Errors403 if the opportunity belongs to another account, 404 if it doesn't exist.


List opportunity tasks

http
GET /v1/opportunities/{opportunityId}/tasks

Returns a paginated list of tasks attached to an opportunity.

Path params

ParamDescription
opportunityIdOpportunity ID

Query params

ParamTypeDefaultDescription
statusstringFilter by to-do, in-progress, or done
pagenumber1Page number
pageSizenumber20Tasks per page (max 100)

Create an opportunity task

http
POST /v1/opportunities/{opportunityId}/tasks

Creates a task on an opportunity. Responds 201 with the new task's id.

Path params

ParamDescription
opportunityIdOpportunity ID

Request body

FieldTypeRequiredDescription
titlestringYesTask title
descriptionstringNoTask description
statusstringNoto-do (default), in-progress, or done
prioritystringNohigh, medium (default), or low
userIdsstring[]NoAccount user IDs assigned to the task
deadlineAtdate-timeNoISO 8601 deadline

Example

bash
curl -X POST https://api-rest.tendios.com/api/v1/opportunities/{opportunityId}/tasks \
  -H "api-key: tend_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Prepare technical proposal", "priority": "high", "deadlineAt": "2026-09-01T09:00:00.000Z" }'

Errors404 if the opportunity doesn't exist.


List opportunity summaries

http
GET /v1/opportunities/{opportunityId}/summaries

Returns the AI-generated summaries for an opportunity.

Path params

ParamDescription
opportunityIdOpportunity ID

Response — array of:

FieldTypeDescription
idstringSummary ID
namestringSummary name
statusstringpending, in_progress, completed, or failed
resultstring?Rendered content in Markdown, present once completed
generatedAtdate-time?When the summary finished generating
createdAtdate-timeCreation timestamp
updatedAtdate-timeLast update timestamp

Errors404 if the opportunity doesn't exist.


Download a summary PDF

http
GET /v1/opportunities/{opportunityId}/summaries/{summaryId}/pdf

Downloads a summary as a PDF. Only available once the summary's status is completed.

Path params

ParamDescription
opportunityIdOpportunity ID
summaryIdSummary ID

Response — binary application/pdf, streamed with Content-Disposition: attachment.

Example

bash
curl https://api-rest.tendios.com/api/v1/opportunities/{opportunityId}/summaries/{summaryId}/pdf \
  -H "api-key: tend_your_key" \
  --output summary.pdf

Errors404 if the opportunity or summary doesn't exist, 409 (code SUMMARY_NOT_READY) if the summary hasn't finished generating yet.


API Key

Get API key info

http
GET /v1/api-key

Returns metadata about the API key in use — rate limit, expiry, last usage.

Example

bash
curl https://api-rest.tendios.com/api/v1/api-key \
  -H "api-key: tend_your_key"

© Tendios