{"openapi":"3.0.0","paths":{"/v1/contacts/{id}":{"get":{"description":"Retrieves a single contact by its unique identifier, including name, email, organization, and other profile details.","operationId":"ContactsCfaController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"ID of the contact to retrieve","schema":{"type":"string"}}],"responses":{"200":{"description":"Single Contact object","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactCfaResponseDto"}}}},"400":{"description":"Bad Request"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"security":[{"authorization":[]}],"summary":"Get a specific contact by ID","tags":["contacts"],"x-controller-class":"ContactsCfaController"},"patch":{"description":"Partially updates an existing contact identified by its unique ID. Supports updating name, email, job position, phone number, and hourly rates. Returns status 209 if the contact was updated but sending the activation or verification email failed.","operationId":"ContactsCfaController_updateOne","parameters":[{"name":"id","required":true,"in":"path","description":"ID of the contact to update","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactsCfaUpdateOneBodyDto"}}}},"responses":{"200":{"description":"Contact updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactCfaResponseDto"}}}},"209":{"description":"Contact updated but sending activation/verification mail was not successful"},"400":{"description":"Bad Request"},"403":{"description":"Forbidden"},"409":{"description":"A remberg user with the same email already exists"}},"security":[{"authorization":[]}],"summary":"Update a contact by ID","tags":["contacts"],"x-controller-class":"ContactsCfaController"},"delete":{"description":"Permanently deletes a contact identified by its unique ID. If the contact is linked to a remberg user account, that account is also deactivated.","operationId":"ContactsCfaController_deleteOne","parameters":[{"name":"id","required":true,"in":"path","description":"ID of the contact to delete","schema":{"type":"string"}}],"responses":{"204":{"description":"Resource deleted"},"400":{"description":"Bad Request"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"security":[{"authorization":[]}],"summary":"Delete a contact by ID","tags":["contacts"],"x-controller-class":"ContactsCfaController"}},"/v1/contacts":{"get":{"description":"Returns a paginated list of contacts. Supports filtering by organization number, creation and update timestamps, and free-text search, as well as sorting and pagination via query parameters.","operationId":"ContactsCfaController_findMany","parameters":[{"name":"organizationNumber","required":false,"in":"query","description":"Specify the organization number the contacts belong to.","schema":{"type":"string"}},{"name":"sortDirection","required":false,"in":"query","description":"Define the sort order of the received payload. (asc/desc)","schema":{"type":"string","enum":["asc","desc"]}},{"name":"sortField","required":false,"in":"query","description":"Specify the field used for sorting.","schema":{"type":"string","enum":["updatedAt","createdAt","firstName","lastName","status"]}},{"name":"page","required":false,"in":"query","description":"Page number.","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Define how many items will be received in the payload per request.(default 20 items, max 1000 items)","schema":{"type":"number"}},{"name":"search","required":false,"in":"query","description":"Allows to filter by the search phrase over fullName, email properties.","schema":{"type":"string"}},{"name":"createdAtFrom","required":false,"in":"query","description":"Filter by createdAt date FROM the provided value as an ISO UTC string. Inclusive.","schema":{"format":"date-time","type":"string"}},{"name":"createdAtUntil","required":false,"in":"query","description":"Filter by createdAt date UNTIL the provided value as an ISO UTC string. Inclusive.","schema":{"format":"date-time","type":"string"}},{"name":"updatedAtFrom","required":false,"in":"query","description":"Filter by updatedAt date FROM the provided value as an ISO UTC string. Inclusive.","schema":{"format":"date-time","type":"string"}},{"name":"updatedAtUntil","required":false,"in":"query","description":"Filter by updatedAt date UNTIL the provided value as an ISO UTC string. Inclusive.","schema":{"format":"date-time","type":"string"}}],"responses":{"200":{"description":"List of Contact objects","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactsCfaFindManyResponseDto"}}}},"400":{"description":"Bad Request"},"403":{"description":"Forbidden"}},"security":[{"authorization":[]}],"summary":"Get a list of contacts","tags":["contacts"],"x-controller-class":"ContactsCfaController"},"post":{"description":"Creates a new contact within the specified organization. Requires a first name, last name, and organization number. Optionally accepts an email to link a remberg user account, as well as job position and phone number.","operationId":"ContactsCfaController_createOne","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactsCfaCreateOneBodyDto"}}}},"responses":{"201":{"description":"Resource created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactCfaResponseDto"}}}},"400":{"description":"Bad Request"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"},"409":{"description":"A remberg user with the same email already exists"}},"security":[{"authorization":[]}],"summary":"Add a new contact to an organization","tags":["contacts"],"x-controller-class":"ContactsCfaController"}}},"info":{"title":"Contacts","description":"The remberg Contacts API description","version":"v1","contact":{}},"tags":[],"servers":[{"url":"https://api.remberg.de"}],"components":{"securitySchemes":{"authorization":{"type":"apiKey","in":"header","name":"authorization"}},"schemas":{"PhoneNumberCfaResponseDto":{"type":"object","properties":{"number":{"type":"string","pattern":"^[0-9 (,),/, ,-]*$"},"countryPrefix":{"type":"string","pattern":"^[0-9]{1,3}$"}}},"HourlyRateCfaResponseDto":{"type":"object","properties":{"value":{"type":"number","description":"Hourly rate value in full currency (e.g. euros)."},"validFrom":{"type":"string","description":"Date from which this rate is effective (YYYY-MM-DD). Empty or omitted for the fallback rate."}},"required":["value"]},"ContactCfaResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"A remberg internal unique identifier for the contact."},"firstName":{"type":"string","description":"The first name of the contact."},"lastName":{"type":"string","description":"The last name of the contact."},"rembergUserEmail":{"type":"string","description":"The email address associated with the contacts's remberg account."},"jobPosition":{"type":"string","description":"The contacts's job position within the organization. This field is optional."},"phoneNumber":{"description":"The phone number of the contact. This field is optional.","allOf":[{"$ref":"#/components/schemas/PhoneNumberCfaResponseDto"}]},"organizationNumber":{"type":"string","description":"A unique identifier of the contact's organization."},"hourlyRates":{"description":"Hourly rates. One entry may have empty validFrom (fallback); others have validFrom set. Full currency (e.g. euros).","type":"array","items":{"$ref":"#/components/schemas/HourlyRateCfaResponseDto"}}},"required":["id","firstName","lastName","rembergUserEmail","organizationNumber"]},"ContactsCfaFindManyResponseDto":{"type":"object","properties":{"count":{"type":"number"},"contacts":{"type":"array","items":{"type":"string"}}},"required":["count","contacts"]},"PhoneNumberCfaBodyDto":{"type":"object","properties":{"number":{"type":"string","pattern":"^[0-9 (,),/, ,-]*$"},"countryPrefix":{"type":"string","pattern":"^[0-9]{1,3}$"}}},"ContactsCfaCreateOneBodyDto":{"type":"object","properties":{"firstName":{"type":"string","description":"The first name of the contact."},"lastName":{"type":"string","description":"The last name of the contact."},"organizationNumber":{"type":"string","description":"A unique identifier of the contact's organization."},"rembergUserEmail":{"type":"string","description":"The email address associated with the contacts's remberg account."},"phoneNumber":{"description":"The phone number of the contact. This field is optional.","allOf":[{"$ref":"#/components/schemas/PhoneNumberCfaBodyDto"}]},"jobPosition":{"type":"string","description":"The contacts's job position within the organization. This field is optional."}},"required":["firstName","lastName","organizationNumber","rembergUserEmail"]},"HourlyRateCfaUpdateBodyDto":{"type":"object","properties":{"value":{"type":"number","description":"Hourly rate value in full currency (e.g. euros). Up to 2 decimal places.","example":40.81},"validFrom":{"type":"string","description":"Date from which this rate is effective (YYYY-MM-DD). Empty or omitted for the fallback rate.","example":"2026-02-03"}},"required":["value"]},"ContactsCfaUpdateOneBodyDto":{"type":"object","properties":{"firstName":{"type":"string","description":"The first name of the contact."},"lastName":{"type":"string","description":"The last name of the contact."},"rembergUserEmail":{"type":"string","description":"The email address associated with the contacts's remberg account."},"phoneNumber":{"type":"object","description":"The phone number of the contact. This field is optional."},"jobPosition":{"type":"string","description":"The contacts's job position within the organization. This field is optional."},"hourlyRates":{"description":"Full list of hourly rates. Exactly one entry must be the fallback rate. Currency format: up to 2 decimal places.","type":"array","items":{"$ref":"#/components/schemas/HourlyRateCfaUpdateBodyDto"}}}}}}}