openapi: 3.0.3
info:
  title: Koulutus- ja valmennuspalvelutieto API
  description: REST-rajapinta, jonka avulla voidaan hakea Työllisyyspalveluvarannossa hallittavien koulutus- ja valmennuspalveluiden tietoja.
  termsOfService: https://tyomarkkinatori.fi/tietoa-palvelusta/tietosuoja-ja-kayttoehdot/kayttoehdot
  contact:
    name: KEHA-keskus
    url: https://tuuttipalvelu.sharepoint.com/sites/ICT-Tuutti/SitePages/Ota-yhteytta.aspx
  version: 1.0.0

servers:
  - url: https://api.ahtp.fi/kipa/p65
    description: KIPA-palvelun tuotantoympäristö (prod)
    x-internal: false
  - url: https://api-qa.ahtp.fi/kipa/p65
    description: KIPA-palvelun testiympäristö
    x-internal: false

tags:
  - name: Palvelukuvaukset
    description: Koulutus- ja valmennuspalveluiden palvelukuvaukset
  - name: Palvelutunnisteet
    description: Koulutus- ja valmennuspalveluiden palvelutunnisteet

paths:
  /v1/koulutus-ja-valmennuspalvelutieto-tarjoaja/palvelukuvaukset:
    get:
      tags:
        - Palvelukuvaukset
      summary: Hae kaikki palvelukuvaukset
      description: Palauttaa kaikki palvelukuvaukset Työllisyyspalveluvarannosta.
      operationId: haePalvelukuvaukset
      parameters:
        - $ref: '#/components/parameters/AcceptHeader'
        - name: muokattu_jalkeen
          in: query
          required: false
          description: Palauta vain palvelukuvaukset, joita on muokattu tämän aikaleiman jälkeen (ISO 8601 -muoto)
          schema:
            type: string
            format: date-time
            maxLength: 20
          example: "2025-09-25T06:06:00Z"
        - name: palveluntuottaja_ytunnus
          in: query
          required: false
          description: "Palauta vain palvelukuvaukset, joissa parametrina annetun y-tunnuksen mukainen organisaatio toimii palveluntuottajana."
          schema:
            type: array
            maxItems: 20
            items:
              type: string
              maxLength: 10
              pattern: '^[0-9]{7}-[0-9]{1}$'
          example:
            - "1234567-8"
            - "2345678-9"
        - name: paikkakunta
          in: query
          required: false
          description: Palauta vain niiden palveluiden kuvaukset, jotka järjestetään annetulla paikkakunnalla.
          schema:
            type: string
            maxLength: 200
        - name: sivu
          in: query
          required: false
          description: Monenneltako sivulta tulokset alkavat (alkaa arvosta 0)
          schema:
            type: integer
            format: int32
            minimum: 0
            maximum: 2000
            default: 0
        - name: maara
          in: query
          required: false
          description: Palautettavien palvelutoteutusten määrä (maksimi 20)
          schema:
            type: integer
            format: int32
            minimum: 1
            maximum: 20
            default: 20
      responses:
        '200':
          $ref: '#/components/responses/Response200Palvelukuvaukset'
        '400':
          $ref: '#/components/responses/Response400'
        '405':
          $ref: '#/components/responses/Response405'
        '406':
          $ref: '#/components/responses/Response406'
        '429':
          $ref: '#/components/responses/Response429'
        '500':
          $ref: '#/components/responses/Response500'
        '501':
          $ref: '#/components/responses/Response501'

  /v1/koulutus-ja-valmennuspalvelutieto-tarjoaja/palvelukuvaukset/{tunniste}:
    get:
      tags:
        - Palvelukuvaukset
      summary: Hae yksittäinen palvelukuvaus tunnisteen perusteella
      description: Palauttaa yksittäisen palvelukuvauksen annetulla tunnisteella.
      operationId: haePalvelukuvausTunnisteella
      parameters:
        - name: tunniste
          in: path
          required: true
          description: Palvelukuvauksen tunniste
          schema:
            type: string
            maxLength: 12
        - $ref: '#/components/parameters/AcceptHeader'
      responses:
        '200':
          $ref: '#/components/responses/Response200Palvelukuvaus'
        '400':
          $ref: '#/components/responses/Response400'
        '404':
          $ref: '#/components/responses/Response404'
        '405':
          $ref: '#/components/responses/Response405'
        '406':
          $ref: '#/components/responses/Response406'
        '429':
          $ref: '#/components/responses/Response429'
        '500':
          $ref: '#/components/responses/Response500'
        '501':
          $ref: '#/components/responses/Response501'
  /v1/koulutus-ja-valmennuspalvelutieto-tarjoaja/palvelutunnisteet:
    get:
      tags:
        - Palvelutunnisteet
      summary: Hae kaikki palvelutunnisteet
      description: Palauttaa kaikki palvelutunnisteet Työllisyyspalveluvarannosta.
      operationId: haePalvelutunnisteet
      parameters:
        - $ref: '#/components/parameters/AcceptHeader'
        - name: sivu
          in: query
          required: false
          description: Monenneltako sivulta tulokset alkavat (alkaa arvosta 0)
          schema:
            type: integer
            format: int32
            minimum: 0
            maximum: 2000
            default: 0
        - name: maara
          in: query
          required: false
          description: Palautettavien palvelutunnisteiden määrä (maksimi 1000)
          schema:
            type: integer
            format: int32
            minimum: 1
            maximum: 1000
            default: 100
      responses:
        '200':
          $ref: '#/components/responses/Response200Palvelutunnisteet'
        '400':
          $ref: '#/components/responses/Response400'
        '405':
          $ref: '#/components/responses/Response405'
        '406':
          $ref: '#/components/responses/Response406'
        '429':
          $ref: '#/components/responses/Response429'
        '500':
          $ref: '#/components/responses/Response500'
        '501':
          $ref: '#/components/responses/Response501'

components:
  parameters:
    AcceptHeader:
      name: Accept
      in: header
      required: false
      description: Hyväksytty mediatyyppi vastaukselle (esim. application/json)
      schema:
        type: string
        maxLength: 512
        default: application/json
      example: application/json;version=1.0
  headers:
    Access-Control-Allow-Origin:
      description: Salli CORS-pyyntö kaikista lähteistä
      schema:
        type: string
        maxLength: 500
        example: "*"
    X-Rate-Limit-Limit:
      description: Maksimimäärä pyyntöjä, jotka asiakas saa tehdä tietyn ajan sisällä
      schema:
        type: integer
        format: int32
        minimum: 0
        maximum: 100
    X-Rate-Limit-Remaining:
      description: Kuinka monta pyyntöä on jäljellä nykyisessä jaksossa
      schema:
        type: integer
        format: int32
        minimum: 0
        maximum: 120
    X-Rate-Limit-Reset:
      description: Aika (sekunteina), jolloin rajoitus nollautuu
      schema:
        type: integer
        format: int32
        minimum: 0
        maximum: 1625247600
    Retry-After:
      description: Aika (sekunteina), jonka jälkeen asiakasjärjestelmä voi tehdä uuden pyynnön
      schema:
        type: integer
        format: int32
        minimum: 0
        maximum: 86400
  schemas:
    LokalisoituTeksti100:
      type: object
      description: Kieliversioitu teksti, jossa avain on kieli (fi, sv, en) ja arvo on teksti merkkijonona
      example:
        fi: "Esimerkkikoulutus"
        sv: "Exempelkurs"
        en: "Example course"
      properties:
        fi:
          type: string
          description: Kieliversioitu teksti suomeksi
          maxLength: 100
        sv:
          type: string
          description: Kieliversioitu teksti ruotsiksi
          maxLength: 100
        en:
          type: string
          description: Kieliversioitu teksti englanniksi
          maxLength: 100
    LokalisoituTeksti200:
      type: object
      description: Kieliversioitu teksti, jossa avain on kieli (fi, sv, en) ja arvo on teksti merkkijonona
      example:
        fi: "Helsinki"
        sv: "Helsingfors"
        en: "Helsinki"
      properties:
        fi:
          type: string
          description: Kieliversioitu teksti suomeksi
          maxLength: 200
        sv:
          type: string
          description: Kieliversioitu teksti ruotsiksi
          maxLength: 200
        en:
          type: string
          description: Kieliversioitu teksti englanniksi
          maxLength: 200
    LokalisoituTeksti500:
      type: object
      description: Kieliversioitu teksti, jossa avain on kieli (fi, sv, en) ja arvo on teksti merkkijonona
      example:
        fi: "Aurakatu 2, 20100 Turku"
        sv: "Auragatan 2, 20100 Åbo"
        en: "Aurakatu 2, 20100 Turku"
      properties:
        fi:
          type: string
          description: Kieliversioitu teksti suomeksi
          maxLength: 500
        sv:
          type: string
          description: Kieliversioitu teksti ruotsiksi
          maxLength: 500
        en:
          type: string
          description: Kieliversioitu teksti englanniksi
          maxLength: 500
    Palvelukuvaus:
      type: object
      description: Koulutus- ja valmennuspalvelun palvelukuvaus
      required:
        - palvelutunniste
        - tila
        - kuvaus
        - alkamisenAjankohta
        - paattymisenAjankohta
        - nonstop
        - kuvauskieli
        - kieli
        - julkaisunAloitusPvm
        - julkaisunPaattymisPvm
        - paikkakunta
        - palvelunjarjestaja
        - palveluntuottaja
        - vastuuorganisaatio
        - palvelukategoria
        - palvelutyyppi
        - rahoitustyyppi
        - maksullisuus
        - palveluluokka
        - kohderyhma
        - asiasana
        - vosKoulutus
        - viimeksiMuokattu
      properties:
        palvelutunniste:
          allOf:
            - $ref: '#/components/schemas/Palvelutunniste'
          description: Palvelukuvauksen yksilöivä tunniste
        tila:
          type: string
          description: Palvelun tila. Rajapinta tarjoaa vain Julkaistu-tilassa olevat palvelut t.s. palvelut, joihin asiakkaan on mahdollista hakea.
          maxLength: 50
        kuvaus:
          type: object
          description: Palvelun kieliversioitu kuvausteksti
          example:
            fi: "Tämä on esimerkkikuvaus palvelulle."
            sv: "Detta är en exempelbeskrivning för tjänsten."
            en: "This is an example description for the service."
          properties:
            fi:
              type: string
              maxLength: 20000
            sv:
              type: string
              maxLength: 20000
            en:
              type: string
              maxLength: 20000
        lisatiedot:
          type: array
          description: Linkit palvelun kieliversioituihin lisätietoihin
          minItems: 0
          maxItems: 30
          items:
            $ref: '#/components/schemas/Verkkosivu'
        alkamisenAjankohta:
          type: string
          format: date
          minLength: 10
          maxLength: 10
          description: Palvelun toteutuksen alkamispäivämäärä
          example: "2024-01-01"
        paattymisenAjankohta:
          type: string
          format: date
          minLength: 10
          maxLength: 10
          description: Palvelun toteutuksen päättymispäivämäärä
          example: "2024-12-31"
        nonstop:
          type: boolean
          description: Tieto siitä, järjestetäänkö sopimuksen mukaan (nonstop)
        kesto:
          allOf:
            - $ref: '#/components/schemas/LokalisoituTeksti500'
          description: Sanallinen kuvaus palvelun kestosta
        haunVerkkosivu:
          allOf:
            - $ref: '#/components/schemas/Verkkosivu'
          description: Linkki, joka ohjaa työvoimakoulutuksen tai -valmennuksen hakemukselle työvoimapalveluiden valtakunnallisten tietojärjestelmäpalvelujen Asioinnissa
        haunUlkoinenVerkkosivu:
          allOf:
            - $ref: '#/components/schemas/Verkkosivu'
          description: Verkko-osoite, josta työvoimapalveluiden valtakunnallisten tietojärjestelmäpalvelujen ulkopuolinen haun verkkosivu löytyy (hakulomake)
        tavoitetutkintoTaiKoulutus:
          allOf:
            - $ref: '#/components/schemas/Tutkinto'
          description: Tavoitetutkinto- tai koulutus ja tähän liittyvä tieto siitä, onko kyseessä tutkinnon osa vai perus- tai ammattitutkinto
        muuTavoitetutkintoTaiKoulutus:
          type: array
          maxItems: 30
          description: Lista muista tavoitetutkinnoista tai -koulutuksista 
          items:
            $ref: '#/components/schemas/Tutkinto'
        kielitaidontasovaatimus:
          type: array
          description: |
            Kielitaidon taso, joka vaaditaan palveluun pääsemiseksi. Eurooppalaisen kielitaidon taso viitekehyksen mukainen arvo koodistosta KIELITAIDON_TASO.
            Jos vaatimuksia on useita, riittää että jokin niistä täyttyy.
          maxItems: 20
          items:
            $ref: '#/components/schemas/Kielitaito'
        kielitaidontasotavoite:
          allOf:
            - $ref: '#/components/schemas/Kielitaito'
          description: Tavoiteltava kielitaidon taso palvelun suorittamisen jälkeen Eurooppalaisen kielitaidon taso viitekehyksen mukainen arvo koodistosta KIELITAIDON_TASO.
        pohjakoulutusvaatimus:
          type: array
          maxItems: 50
          description: |
            Koulutus, joka vaaditaan palveluun pääsemiseksi. 
            Jos koulutusvaatimuksia on useita tarkoittaa se sitä, että jokin niistä on vaatimuksena mutta ei kaikki. 
            Koulutukset koodistosta TYÖNHAKUPROFIILI_KOULUTUS.
          externalDocs:
            url: https://tyomarkkinatori.fi/api/codes/v1/kopa/TY%C3%96NHAKUPROFIILI_KOULUTUS/koodit
          items:
            type: string
            format: koodi
            maxLength: 10
            example: "201101"
        osaaminen:
          type: array
          maxItems: 20
          description: Tieto palveluun liittyvästä osaamisesta koodistosta ESCO_OSAAMINEN.
          items:
            $ref: '#/components/schemas/ESCOOsaaminen'
        ammatti:
          type: array
          maxItems: 20
          description: Palveluun liittyvät ammatit (ISCO/ESCO) koodistosta ESCO_AMMATTI
          items:
            $ref: '#/components/schemas/ESCOAmmatti'
        kuvauskieli:
          type: array
          description: Kieli, jolla palvelutoteutus on kuvattu Työmarkkinatorilla
          minItems: 1
          maxItems: 3
          items:
            type: string
            enum: [fi, en, sv]
            minLength: 2
            maxLength: 2
            description: Palvelukuvauksen kieli
            example: "fi"
        kieli:
          type: array
          minItems: 1
          maxItems: 20
          description: Palvelun toteutuksessa käytettävät kielet koodistosta KIELI.
          externalDocs:
            url: https://tyomarkkinatori.fi/api/codes/v1/kopa/KIELI/koodit
          items:
            type: string
            format: koodi
            minLength: 2
            maxLength: 3
            example: "fi"
        kohderyhma:
          type: array
          minItems: 1
          maxItems: 60
          description: Kohderymäluokitukset koodistosta KOHDERYHMÄLUOKAT.
          externalDocs:
            url: https://tyomarkkinatori.fi/api/codes/v1/kopa/KOHDERYHM%C3%84LUOKAT/koodit
          items:
            type: string
            format: koodi
            maxLength: 10
            example: "L1.11"
        julkaisunAloitusPvm:
          type: string
          format: date
          maxLength: 10
          description: Päivämäärä, jolloin palvelutoteutuksen julkaisun voimassaolo alkaa Työmarkkinatorilla. Määrittää myös hakuajan alkamisen. Voimassa ko. päivän alusta alkaen.
          example: "2025-01-01"
        julkaisunPaattymisPvm:
          type: string
          format: date
          maxLength: 10
          description: Päivämäärä, jolloin palvelutoteutuksen julkaisun voimassaolo päättyy Työmarkkinatorilla. Määrittää myös hakuajan päättymisen. Voimassa ko. päivän päättymiseen asti.
          example: "2025-03-31"
        tyyppi:
          type: string
          description: Palvelutoteutuksen tyyppi
          enum:
            - Verkkototeutus
            - Paikan päällä
            - Monimuoto
        toteutuksenVerkkosivu:
          allOf:
            - $ref: '#/components/schemas/Verkkosivu'
          description: Tieto toteutuksen verkkosivusta. Pakollinen tieto, jos toteutuksen tyyppi on Verkkototeutus tai Monimuoto
        osoite:
          allOf:
            - $ref: '#/components/schemas/LokalisoituTeksti500'
          description: Toteutuksen tarkat osoitetiedot. Pakollinen tieto, jos toteutuksen tyyppi on "Paikan päällä" tai "Monimuoto".  
        paikkakunta:
          type: array
          minItems: 0
          maxItems: 30
          description: Palvelutoteutuksen paikkakunnat (kaupunki/kunta). Pakollinen tieto, jos toteutuksen tyyppi on "Paikan päällä" tai "Monimuoto".
          items:
            $ref: '#/components/schemas/LokalisoituTeksti200'
        paikkojenLukumaara:
          type: integer
          format: int32
          minimum: 1
          maximum: 9999
          description: Palvelutoteutuksen paikkojen lukumäärä
        palvelunjarjestaja:
          allOf:
            - $ref: '#/components/schemas/Organisaatio'
          description: Palvelun järjestäjä
        palveluntuottaja:
          allOf:
            - $ref: '#/components/schemas/Organisaatio'
          description: Palvelun tuottaja
        tyonantaja:
          type: array
          maxItems: 20
          description: Palvelutoteutuksen työnantajat
          items:
            $ref: '#/components/schemas/Organisaatio'
        vastuuorganisaatio:
          allOf:
            - $ref: '#/components/schemas/Organisaatio'
          description: Organisaatio, joka on vastuussa palvelun järjestämisestä / omistaa palvelukuvauksen
        palvelukategoria:
          type: string
          format: koodi
          maxLength: 10
          description: |
            Kategoriat, joihin työllisyyspalveluja voidaan luokitella tai kategorisoida yleisimpien palvelutuotteita sisällöllisesti toisistaan erottavien ominaisuuksien mukaan.
            Parametrin arvo asetetaan koodistosta PALVELUKATEGORIAT.
          externalDocs:
            url: https://tyomarkkinatori.fi/api/codes/v1/kopa/PALVELUKATEGORIAT/koodit
          example: "PK2.1"
        palvelutyyppi:
          type: string
          description: Palvelun tyyppi.
          enum: [Palvelu, Lupa tai velvoite, Ammattipätevyys]
          example: Palvelu
        rahoitustyyppi:
          type: string
          description: Onko palvelu julkinen vai yksityinen.
          enum: [Julkinen palvelu, Yksityinen palvelu]
          example: Julkinen palvelu
        maksullisuus:
          type: string
          description: Onko palvelu maksullinen vai maksuton.
          enum: [Maksullinen, Maksuton, Muu]
          example: Maksuton
        maksullisuudenLisatieto:
          allOf:
            - $ref: '#/components/schemas/LokalisoituTeksti500'
          description: Sanallinen lisätieto maksullisuudesta
        lait:
          type: array
          maxItems: 10
          description: Palveluun liittyvät lait
          items:
            $ref: '#/components/schemas/Laki'
        palveluluokka:
          type: array
          minItems: 1
          maxItems: 4
          description: Palveluluokitukset koodistosta PALVELULUOKKA.
          externalDocs:
            url: https://tyomarkkinatori.fi/api/codes/v1/kopa/PALVELULUOKKA/koodit
          items:
            type: string
            format: koodi
            maxLength: 10
            example: "P6"
        asiasana:
          type: array
          minItems: 1
          maxItems: 10
          description: | 
            Palvelujen asiasanakuvailussa käytetään käsitteitä seuraavista sanasto- ja ontologiaresursseista: 
            * Julkishallinnon ontologia JUHO 
            * Julkisen hallinnon palveluontologia JUPO 
            * Liiketoimintaontologia LIITO
            * Terveyden ja hyvinvoinnin ontologia TERO 
            * TSR-ontologia 
            * Yleinen suomalainen ontologia YSO.
            * Kokoelma suomalaisia ydinontologioita, KOKO.
          items:
            $ref: '#/components/schemas/Asiasana'
        vosKoulutus:
          type: boolean
          description: |
            Kytkin, joka kertoo onko kyseessä VOS-koulutus vai ei. 
            VOS- eli valtionosuusrahoitteiset (ammatilliseen tutkintoon tai osatutkintoon johtavat koulutukset) ovat OKM:n rahoittamia.
        viimeksiMuokattu:
          type: string
          format: date-time
          maxLength: 20
          description: |
            Tieto siitä, koska tietoa on viimeksi muokattu.

            Huomio: Koska rajapinta ei sisällä kaikkia kannassa olevia toteutuksen, tarjouksen ja palvelukuvauksen kenttiä, niin tapahtunut muokkaus ei välttämättä ole liittynyt juuri niihin kenttiin mitä rajapinta palauttaa.
          example: "2025-09-03T12:34:56Z"
    Organisaatio:
      type: object
      description: Organisaation tiedot
      required:
        - nimi
      properties:
        yTunnus:
          type: string
          maxLength: 10
          pattern: '^[0-9]{7}-[0-9]{1}$'
          description: Rekisteriviranomaisen antama yksilöivä tunnus elinkeinotoimintaa harjoittavalle henkilölle tai oikeushenkilölle.
          example: "1234567-8"
        oidTunniste:
          type: string
          maxLength: 100
          pattern: '^[A-Za-z0-9.-]*$'
          description: |
            OID-yksilöintitunnus. 
            Object Identifier -tunniste. ks. https://fi.wikipedia.org/wiki/OID 
            ISO OID -yksilöintijärjestelmän mukainen kansainvälinen yksilöllinen tunniste, jonka tietystä kohteesta vastaava taho on antanut kohteelle.
          example: "1.2.246.562.10.12345678901"
        nimi:
          $ref: '#/components/schemas/LokalisoituTeksti100'
        ylatasonOrganisaatio:
          allOf:
            - $ref: '#/components/schemas/Organisaatio'
          description: "Organisaatio, jonka alaisuuteen tämä organisaatio kuuluu. Toisin sanoen organisaatiohierarkiassa ylemmällä tasolla oleva organisaatio (parent)."
    Laki:
      type: object
      description: Lain tiedot
      required:
        - nimi
        - verkkoOsoite
      properties:
        nimi:
          allOf:
            - $ref: '#/components/schemas/LokalisoituTeksti500'
          description:  Lain nimi, johon palvelu pohjautuu
        verkkoOsoite:
          allOf:
            - $ref: '#/components/schemas/Verkkosivu'
          description:  Verkko-osoite, josta laki löytyy
    Verkkosivu:
      type: object
      description: Verkkosivun tiedot
      required:
        - osoite
      properties:
        nimi:
          allOf:
            - $ref: '#/components/schemas/LokalisoituTeksti100'
          description: Verkkosivun nimi
        osoite:
          allOf:
            - $ref: '#/components/schemas/LokalisoituTeksti500'
          description: Verkkosivun osoite (URL)
    ESCOAmmatti:
      type: object
      description: ESCO-ammattiluokituksen mukaisen ammatin tiedot koodistosta ESCO_AMMATTI
      required:
        - uri
        - koodi
        - nimi
      properties:
        uri:
          type: string
          description: ESCO-ammattiluokituksen URI
          maxLength: 500
          example: "http://data.europa.eu/esco/occupation/42abcbcb-721b-4da6-9c06-f6951969d056"
        koodi:
          type: string
          description: ESCO-ammattiluokituksen koodi
          externalDocs:
            url: https://tyomarkkinatori.fi/api/codes/v1/kopa/ESCO_AMMATTI/koodit
          format: koodi
          maxLength: 20
          example: "1324.3.2.27"
        nimi:
          $ref: '#/components/schemas/LokalisoituTeksti200'
    ESCOOsaaminen:
      type: object
      description: ESCO-osaamisluokituksen mukaisen osaamisen tiedot koodistosta ESCO_OSAAMINEN
      required:
        - uri
        - koodi
        - nimi
      properties:
        uri:
          type: string
          description: ESCO-osaamisluokituksen URI
          maxLength: 500
          example: "http://data.europa.eu/esco/skill/3c9fc332-97e4-409a-8c32-e81fa552e882"
        koodi:
          type: string
          description: ESCO-osaamisluokituksen koodi
          externalDocs:
            url: https://tyomarkkinatori.fi/api/codes/v1/kopa/ESCO_OSAAMINEN/koodit
          minLength: 36
          maxLength: 36
          example: "3c9fc332-97e4-409a-8c32-e81fa552e882"
        nimi:
          $ref: '#/components/schemas/LokalisoituTeksti200'
    Asiasana:
      type: object
      description: Asiasanan tiedot
      required:
        - asiasana
        - paaluokanVerkkoOsoite
        - verkkoOsoite
      properties:
        asiasana:
          $ref: '#/components/schemas/LokalisoituTeksti200'
        ontologiatyyppi:
          type: string
          description: Määrittelee mistä ontologiasta tai käsitekirjastosta asiasana on peräisin
          enum: [JUHO, JUPO, LIITO, TERO, TSR, YSO, KOKO]
        verkkoOsoite:
          type: string
          format: uri
          description: Asiasanan verkko-osoite
          maxLength: 200
        paaluokanVerkkoOsoite:
          type: string
          format: uri
          description: Asiasanan pääluokan verkko-osoite
          maxLength: 200
    Tutkinto:
      type: object
      description: Tutkinnon tiedot
      required:
        - tutkinto
        - tyyppi
      properties:
        tutkinto:
          type: string
          format: koodi
          maxLength: 10
          description: Tutkinto- tai koulutus koodistosta TYÖNHAKUPROFIILI_KOULUTUS.
          externalDocs:
            url: https://tyomarkkinatori.fi/api/codes/v1/kopa/TY%C3%96NHAKUPROFIILI_KOULUTUS/koodit
        tyyppi:
          type: string
          description: Tieto siitä onko kyseessä tutkinnon osa vai perus- tai ammattitutkinto
          enum: ["Tutkinnon osa", "Perus- tai ammattitutkinto"]
    Palvelutunniste:
      type: object
      description: Palvelun tunnisteen tiedot
      required:
        - tunniste
        - nimi
      properties:
        tunniste:
          type: string
          maxLength: 12
          description: Palvelukuvauksen yksilöivä tunniste
          example: "25012341"
        nimi:
          allOf:
            - $ref: '#/components/schemas/LokalisoituTeksti100'
          description: Palvelukuvauksen nimi
    Kielitaito:
      type: object
      description: Kielitaidon tiedot
      required:
        - kieli
        - kielitaidonTaso
      properties:
        kieli:
          type: string
          format: koodi
          description: Kieli koodistosta KIELI
          externalDocs:
            url: https://tyomarkkinatori.fi/api/codes/v1/kopa/KIELI/koodit
          minLength: 2
          maxLength: 3
          example: "en"
        kielitaidonTaso:
          type: string
          format: koodi
          description: Eurooppalaisen kielitaidon taso viitekehyksen mukainen arvo koodistosta KIELITAIDON_TASO.
          externalDocs:
            url: https://tyomarkkinatori.fi/api/codes/v1/kopa/KIELITAIDON_TASO/koodit
          minLength: 1
          maxLength: 4
          example: "A2"
    ApiVirhe:
      type: object
      description: Rajapinnan palauttama IETF RFC9457 standardin (Problem Details for HTTP APIs) mukainen virheviesti
      properties:
        type: 
          description: Osoite joka yksilöi virhetyypin
          type: string
          maxLength: 500
          format: uri-reference
          example: 'about:blank'
        title:
          description: Tiivistelmä virhetyypistä
          type: string
          maxLength: 200
          example: Palvelukuvausta ei löytynyt
        status:
          description: HTTP tilakoodi
          type: integer
          format: int32
          minimum: 100
          maximum: 599
          example: 404
        detail:
          description: Virhettä kuvaava tarkempi viesti
          type: string
          maxLength: 1024
          example: 'Palvelukuvausta tunnisteella 1234567890 ei löytynyt.'
        instance:  
          description: Virheellisen tiedon yksilöivä osoite
          type: string
          maxLength: 500
          format: uri-reference
          example: '/palvelukuvaus/1234567890'
        timestamp:
          type: string
          format: date-time
          maxLength: 20
          description: Virheen aikaleima
          example: '2023-10-30T10:38:21Z'
      required:
        - type
        - title
        - status
  responses:
    Response200Palvelukuvaukset:
      description: Lista palvelukuvauksista (maks. 20 kerralla, sivutettuna)
      headers:
        Access-Control-Allow-Origin:
          $ref: '#/components/headers/Access-Control-Allow-Origin'
        X-Rate-Limit-Limit:
          $ref: '#/components/headers/X-Rate-Limit-Limit'
        X-Rate-Limit-Remaining:
          $ref: '#/components/headers/X-Rate-Limit-Remaining'
        X-Rate-Limit-Reset:
          $ref: '#/components/headers/X-Rate-Limit-Reset'
      content:
        application/json:
          schema:
            type: array
            maxItems: 20
            items:
              $ref: '#/components/schemas/Palvelukuvaus'
    Response200Palvelukuvaus:
      description: Yksittäinen palvelukuvaus
      headers:
        Access-Control-Allow-Origin:
          $ref: '#/components/headers/Access-Control-Allow-Origin'
        X-Rate-Limit-Limit:
          $ref: '#/components/headers/X-Rate-Limit-Limit'
        X-Rate-Limit-Remaining:
          $ref: '#/components/headers/X-Rate-Limit-Remaining'
        X-Rate-Limit-Reset:
          $ref: '#/components/headers/X-Rate-Limit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Palvelukuvaus'
    Response200Palvelutunnisteet:
      description: Lista palvelutunnisteista
      headers:
        Access-Control-Allow-Origin:
          $ref: '#/components/headers/Access-Control-Allow-Origin'
        X-Rate-Limit-Limit:
          $ref: '#/components/headers/X-Rate-Limit-Limit'
        X-Rate-Limit-Remaining:
          $ref: '#/components/headers/X-Rate-Limit-Remaining'
        X-Rate-Limit-Reset:
          $ref: '#/components/headers/X-Rate-Limit-Reset'
      content:
        application/json:
          schema:
            type: array
            maxItems: 20
            items:
              $ref: '#/components/schemas/Palvelutunniste'
    Response400:
      description: Virheellinen pyyntö
      headers:
        Access-Control-Allow-Origin:
          $ref: '#/components/headers/Access-Control-Allow-Origin'
        X-Rate-Limit-Limit:
          $ref: '#/components/headers/X-Rate-Limit-Limit'
        X-Rate-Limit-Remaining:
          $ref: '#/components/headers/X-Rate-Limit-Remaining'
        X-Rate-Limit-Reset:
          $ref: '#/components/headers/X-Rate-Limit-Reset'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ApiVirhe'
    Response404:
      description: Palvelukuvausta ei löytynyt
      headers:
        Access-Control-Allow-Origin:
          $ref: '#/components/headers/Access-Control-Allow-Origin'
        X-Rate-Limit-Limit:
          $ref: '#/components/headers/X-Rate-Limit-Limit'
        X-Rate-Limit-Remaining:
          $ref: '#/components/headers/X-Rate-Limit-Remaining'
        X-Rate-Limit-Reset:
          $ref: '#/components/headers/X-Rate-Limit-Reset'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ApiVirhe'
    Response405:
      description: Metodia ei tueta
      headers:
        Access-Control-Allow-Origin:
          $ref: '#/components/headers/Access-Control-Allow-Origin'
        X-Rate-Limit-Limit:
          $ref: '#/components/headers/X-Rate-Limit-Limit'
        X-Rate-Limit-Remaining:
          $ref: '#/components/headers/X-Rate-Limit-Remaining'
        X-Rate-Limit-Reset:
          $ref: '#/components/headers/X-Rate-Limit-Reset'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ApiVirhe'
    Response406:
      description: Ei tuettu mediatyyppi
      headers:
        Access-Control-Allow-Origin:
          $ref: '#/components/headers/Access-Control-Allow-Origin'
        X-Rate-Limit-Limit:
          $ref: '#/components/headers/X-Rate-Limit-Limit'
        X-Rate-Limit-Remaining:
          $ref: '#/components/headers/X-Rate-Limit-Remaining'
        X-Rate-Limit-Reset:
          $ref: '#/components/headers/X-Rate-Limit-Reset'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ApiVirhe'
    Response429:
      description: Liiallinen pyyntömäärä
      headers:
        Access-Control-Allow-Origin:
          $ref: '#/components/headers/Access-Control-Allow-Origin'
        X-Rate-Limit-Limit:
          $ref: '#/components/headers/X-Rate-Limit-Limit'
        X-Rate-Limit-Remaining:
          $ref: '#/components/headers/X-Rate-Limit-Remaining'
        X-Rate-Limit-Reset:
          $ref: '#/components/headers/X-Rate-Limit-Reset'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ApiVirhe'
    Response500:
      description: Palvelinvirhe
      headers:
        Access-Control-Allow-Origin:
          $ref: '#/components/headers/Access-Control-Allow-Origin'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ApiVirhe'
    Response501:
      description: Toiminnallisuutta ei ole toteutettu
      headers:
        Access-Control-Allow-Origin:
          $ref: '#/components/headers/Access-Control-Allow-Origin'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ApiVirhe'
security: []
