{"openapi":"3.1.0","info":{"title":"Things Projects API","description":"This specification describes the Projects API of the KPN Things Platform.","contact":{"name":"KPN Things Support","url":"https://portal.kpnthings.com/support","email":"iot-developer@kpn.com"},"version":"0.8.0"},"servers":[{"url":"https://api.kpnthings.com","description":"Things API Environment"}],"paths":{"/projects":{"get":{"summary":"Retrieve projects, filtered by search term and / or client ID","description":"Retrieve all projects that match the query parameters given. If a search parameter is provided, projects whose name or description (partially) match are returned.","operationId":"searchProjects","parameters":[{"$ref":"#/components/parameters/cursor"},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/sort"},{"name":"q","in":"query","description":"Include only projects whose name or description contain the search term.  Matching is done case-insensitively.","style":"form","explode":true,"schema":{"type":"string","minLength":1,"example":null},"example":"track"},{"name":"clientId","in":"query","description":"Include only projects owned by the client matching clientId.","style":"form","explode":true,"schema":{"type":"string","format":"uuid","example":null}},{"name":"createdBefore","in":"query","description":"Include only projects created before the provided date and time. The date-time must be in ISO 8601 format.","style":"form","explode":true,"schema":{"type":"string","format":"date-time","example":null},"example":"2025-05-01T00:00:00Z"},{"name":"createdSince","in":"query","description":"Include only projects created at or after the provided date and time. The date-time must be in ISO 8601 format.","style":"form","explode":true,"schema":{"type":"string","format":"date-time","example":null},"example":"2025-05-01T00:00:00Z"},{"name":"modifiedBefore","in":"query","description":"Include only projects modified before the provided date and time. The date-time must be in ISO 8601 format.","style":"form","explode":true,"schema":{"type":"string","format":"date-time","example":null},"example":"2025-04-01T00:00:00Z"},{"name":"modifiedSince","in":"query","description":"Include only projects modified at or after the provided date and time. The date-time must be in ISO 8601 format.","style":"form","explode":true,"schema":{"type":"string","format":"date-time","example":null},"example":"2025-04-01T00:00:00Z"}],"responses":{"200":{"description":"Page of filtered projects. Only projects that are accessible to the caller are returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageOfProjects","example":null}}}},"400":{"$ref":"#/components/responses/badRequest"}},"security":[{"BearerAuth":["project.read"]}]}},"/projects/{projectId}":{"get":{"summary":"Retrieve a project by ID","operationId":"getProject","parameters":[{"name":"projectId","in":"path","description":"Project identifier","required":true,"style":"simple","schema":{"type":"string","format":"uuid","example":null}}],"responses":{"200":{"description":"The project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project","example":null}}}}},"security":[{"BearerAuth":["project.read"]}]},"head":{"summary":"Checks whether a project exists","operationId":"projectExists","parameters":[{"name":"projectId","in":"path","description":"Project identifier","required":true,"style":"simple","schema":{"type":"string","format":"uuid","example":null}}],"responses":{"204":{"description":"The project exists and is accessible to the caller (or provided clientId)"}},"security":[{"BearerAuth":["project.read"]}]}}},"components":{"schemas":{"Page":{"type":"object","description":"Page of items","properties":{"items":{"type":"array","items":{},"example":null},"next":{"type":"string","format":"uri","description":"Pagination link pointing to the next page. Only provided when not at the last page.","example":null},"prev":{"type":"string","format":"uri","description":"Pagination link pointing to the previous page. Only provided when not at the first page.","example":null}},"required":["items"],"title":"Page","example":null},"NonBlankString":{"type":"string","description":"Must not be empty or contain only whitespace.","minLength":1,"pattern":".*\\S.*","example":null},"ProjectDefinition":{"type":"object","description":"Describes the type and constraints of a KPN Things Project","properties":{"type":{"type":"string","description":"The project type. Known values include: ASSET_INSURANCE_E2E, ASSET_TRACKING_E2E, ASSET_TRACKING_RESELLER, CONDITION_MONITORING_E2E, CUSTOM, CUSTOM_RESELLER, EXPLORER, EXPLORER_WITH_M2M, FILL_LEVEL_E2E, FILL_LEVEL_RESELLER, FREEMIUM, FREEMIUM_WITH_M2M, MODULAR, MODULAR_RESTRICTED, TAILORED and UNLIMITED","example":"FREEMIUM"},"maxDevices":{"type":"integer","format":"int32","description":"The maximum number of devices that can be registered under a project. -1 means unbounded.","example":3},"maxDestinations":{"type":"integer","format":"int32","description":"The maximum number of destinations that can be registered under a project. -1 means unbounded.","example":3},"maxDeviceGroups":{"type":"integer","format":"int32","description":"The maximum number of device groups that can be registered under a project. -1 means unbounded.","example":3}},"required":["type"],"title":"ProjectDefinition","example":null},"Project":{"type":"object","description":"Project in KPN Things that serves as a container for devices, destinations, flows and metadata","properties":{"id":{"type":"string","format":"uuid","description":"The entity ID","example":"99086060-b099-416e-a321-53220f4edf99","readOnly":true},"clientId":{"type":"string","format":"uuid","description":"ID of owning client","example":"b7b953c9-b137-4d28-8d29-d266c720bc78"},"createdAt":{"type":"string","format":"date-time","description":"The timestamp when the project is created in the system.","example":"2024-12-31T23:00:00.000Z","readOnly":true},"createdBy":{"type":"string","description":"The user who created the project.","example":"principal/9ebbb3b1-1b6b-46e7-8d58-bb8fe7ae24d4","readOnly":true},"modifiedAt":{"type":"string","format":"date-time","description":"The timestamp when the project is last modified in the system.","example":"2024-12-31T23:00:00.000Z","readOnly":true},"modifiedBy":{"type":"string","description":"The user who last modified the project.","example":"principal/9ebbb3b1-1b6b-46e7-8d58-bb8fe7ae24d4","readOnly":true},"name":{"allOf":[{"$ref":"#/components/schemas/NonBlankString","example":null},{"type":"string","description":"The project name","example":"My first project"}],"example":null},"description":{"allOf":[{"$ref":"#/components/schemas/NonBlankString","example":null},{"type":"string","description":"A short description of the project","example":"Project to explore KPN Things"}],"example":null},"definition":{"$ref":"#/components/schemas/ProjectDefinition","example":null}},"required":["clientId","definition","id","name"],"title":"Project","example":null},"PageOfProjects":{"type":"object","allOf":[{"$ref":"#/components/schemas/Page","example":null},{"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Project"},"example":null}},"example":null}],"description":"A paginated list of projects","title":"PageOfProjects","example":null},"Problem":{"type":"object","description":"Error information details","properties":{"type":{"type":"string","format":"uri-reference","default":"about:blank","description":"A URI reference that uniquely identifies the problem type only in the\ncontext of the provided API. Opposed to the specification in RFC-9457,\nit is neither recommended to be dereferenceable and point to a\nhuman-readable documentation nor globally unique for the problem type.","example":"/some/uri-reference"},"title":{"type":"string","description":"A short summary of the problem type. Written in English and readable\nfor engineers, usually not suited for non technical stakeholders and\nnot localized.","example":"some title for the error situation"},"status":{"type":"integer","format":"int32","description":"The HTTP status code generated by the origin server for this occurrence\nof the problem.","example":400,"exclusiveMaximum":600,"minimum":100},"detail":{"type":"string","description":"A human readable explanation specific to this occurrence of the\nproblem that is helpful to locate the problem and give advice on how\nto proceed. Written in English and readable for engineers, usually not\nsuited for non technical stakeholders and not localized.","example":"Some description for the error situation"},"instance":{"type":"string","format":"uri-reference","description":"A URI reference that identifies the specific occurrence of the problem,\ne.g. by adding a fragment identifier or sub-path to the problem type.\nMay be used to locate the root of this problem in the source code.","example":"/some/uri-reference#specific-occurrence-context"}},"title":"Problem","example":null}},"responses":{"badRequest":{"description":"Request is missing required information or invalid","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"parameters":{"cursor":{"name":"cursor","in":"query","description":"String that encodes all necessary information to retrieve a page.","style":"form","explode":true,"schema":{"type":"string","format":"cursor"}},"limit":{"name":"limit","in":"query","description":"Limit the number of results (per page).","style":"form","explode":true,"schema":{"type":"integer","default":50}},"sort":{"name":"sort","in":"query","description":"Sorting fields separated by comma. Default order is Ascending (ASC), minus(-) should be used in front of field name for Descending (DESC) order.","style":"form","explode":true,"schema":{"type":"string"},"example":"createdAt,-name"}},"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}}}