{"openapi":"3.1.0","info":{"title":"User Profile","description":"DEPRECATED. Previously used to manage player profile data. This service is being phased out in favor of the more flexible Key/Value Store.","version":"0.1.0"},"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"},"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"statusMessage":{"description":"Provides information about the service status.","type":"string"},"apiError":{"description":"The error object returned by the API when an error occurs","type":"object","properties":{"error":{"description":"HTTP error message","type":"string"},"code":{"description":"Fastify error code","type":"string"},"message":{"description":"User error message","type":"string"},"statusCode":{"description":"HTTP status code","type":"number"}},"required":["error","message","statusCode"]},"httpError":{"description":"HTTP error message","type":"string"},"errorCode":{"description":"Fastify error code","type":"string"},"errorMessage":{"description":"User error message","type":"string"},"errorStatusCode":{"description":"HTTP status code","type":"number"},"organizationHeader":{"description":"Organization header automatically added by the load balancer","type":"object","properties":{"x-m2-organization-id":{"description":"The ID of an organization","type":"string"}},"required":["x-m2-organization-id"]},"organizationId":{"description":"The ID of an organization","type":"string"},"getProfileReplySchema":{"description":"The profile of a given user in an organization.","type":"object","properties":{"username":{"type":"string"},"profilePictureUrl":{"type":"string"},"avatar":{"type":"object","properties":{"url":{"type":"string"},"datasourceId":{"type":"string"},"objectDefinitionId":{"type":"string"}},"required":["url","datasourceId","objectDefinitionId"]},"evmLinkedWalletAddress":{"description":"The linked EVM wallet address for the user, if verified.","type":"string"}}},"putProfileRequestSchema":{"description":"The request body for PUT /profile","type":"object","properties":{"username":{"description":"The username of a user. It might have restricted length and characters, based on the organization's settings.","type":"string"},"profilePicture":{"description":"This field is populated by a middleware when a file is sent as body. It should not be set by the client.","log_field":false},"profilePictureObjectDefinitionId":{"description":"The datasource ID and object definition ID of the profile picture object. If null, the profile picture will be unset.","anyOf":[{"type":"object","properties":{"datasourceId":{"type":"string"},"objectDefinitionId":{"type":"string"}},"required":["datasourceId","objectDefinitionId"]},{"type":"null"}]},"avatarObjectDefinitionId":{"description":"The datasource ID and object definition ID of the avatar object. If null, the avatar will be unset.","anyOf":[{"type":"object","properties":{"datasourceId":{"type":"string"},"objectDefinitionId":{"type":"string"}},"required":["datasourceId","objectDefinitionId"]},{"type":"null"}]}}},"Username":{"description":"The username of a user. It might have restricted length and characters, based on the organization's settings.","type":"string"},"putProfileReplySchema":{"description":"The user's profile after upserting it.","type":"object","properties":{"username":{"type":"string"},"profilePictureUrl":{"type":"string"},"avatarObjectDefinitionId":{"type":"object","properties":{"datasourceId":{"type":"string"},"objectDefinitionId":{"type":"string"}},"required":["datasourceId","objectDefinitionId"]}}},"PutUsernamesDenylistRequestSchema":{"description":"An array of usernames to add to the denylist","type":"array","items":{"type":"string"}},"PutUsernamesDenylistResponse":{"description":"The response of adding usernames to the denylist in case some are already in use","type":"object","allOf":[{"description":"The error object returned by the API when an error occurs","type":"object","properties":{"error":{"description":"HTTP error message","type":"string"},"code":{"description":"Fastify error code","type":"string"},"message":{"description":"User error message","type":"string"},"statusCode":{"description":"HTTP status code","type":"number"}},"required":["error","message","statusCode"]},{"type":"object","properties":{"usedUsernames":{"description":"An array of usernames that need to be removed before the denylist is modified","type":"array","items":{"type":"string"}}},"required":["usedUsernames"]}]},"PostUsernamesDenylistRequestSchema":{"description":"A record of usernames to add to the denylist, specifying replacements if they are already in use","type":"object","additionalProperties":{"description":"The replacement username if the username is already in use","$ref":"#/components/schemas/Username"}},"PostUsernamesDenylistResponse":{"description":"The response of adding usernames to the denylist and replacing if needed, in case some couldn't be added","type":"object","allOf":[{"description":"The error object returned by the API when an error occurs","type":"object","properties":{"error":{"description":"HTTP error message","type":"string"},"code":{"description":"Fastify error code","type":"string"},"message":{"description":"User error message","type":"string"},"statusCode":{"description":"HTTP status code","type":"number"}},"required":["error","message","statusCode"]},{"type":"object","properties":{"usernamesWithErrors":{"description":"An array of usernames that could not be added to the denylist","type":"array","items":{"type":"string"}}},"required":["usernamesWithErrors"]}]},"DeleteUsernamesDenylistRequestSchema":{"description":"An array of usernames to remove from the denylist","type":"array","items":{"type":"string"}},"DeleteUsernamesDenylistResponseSchema":{"description":"The response of deleting usernames from the denylist","type":"object","properties":{"usernamesDeleted":{"type":"array","items":{"description":"An array of usernames that were removed from the denylist","type":"string"}},"usernamesInUse":{"type":"array","items":{"description":"An array of usernames that are in use and cannot be removed","type":"string"}}},"required":["usernamesDeleted","usernamesInUse"]}}},"paths":{"/":{"get":{"operationId":"getProfile","summary":"Fetch a user's profile","tags":["Profile"],"description":"Returns the profile of the user making the request.","parameters":[{"schema":{"type":"string"},"in":"header","name":"x-m2-organization-id","required":true,"description":"The ID of an organization"}],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"The profile of a given user in an organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/getProfileReplySchema"}}}}}},"put":{"operationId":"updateProfile","summary":"Upserts a user's profile","tags":["Profile"],"description":"Updates the profile of the user making the request. If the user does not have a profile, one will be created.\nThe profile picture and avatar of a user can be unset using this endpoint.\n\nThe endpoint accepts a JSON object as body, which allows upserting various fields of the user's profile.\nAn image from the user's collection can be set a profile picture by sending its datasource and object definition IDs in the body.\n\nThe endpoint also accepts a file (image) in binary format as body, which will be uploaded and saved as the user's profile picture.\nThe Content-Type header has to be set to 'multipart/form-data' when sending a file.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/putProfileRequestSchema"}}}},"parameters":[{"schema":{"type":"string"},"in":"header","name":"x-m2-organization-id","required":true,"description":"The ID of an organization"}],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"The user's profile after upserting it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/putProfileReplySchema"}}}}}}},"/username/deny/":{"post":{"operationId":"addUsernamesToDenylist","summary":"Ban and replace usernames","tags":["Profile"],"description":"This endpoint adds the provided list of usernames to the (possibly already existing) denylist. If a username is already in use, it is replaced with the provided replacement username.\nThe request must contain a list of pairs of usernames: one to be added to the denylist, and the other to replace it if it is already in use.\nIf a username is already in the denylist, it is skipped.\n\nThis operation can be totally or partially successful. If some usernames could not be added to the denylist, the response will contain a list of those usernames.\n\nNone of the usernames in the request need to obey the restrictions regarding length and allowed characters.\n\nImportant note: denylists rely on unique usernames being enforced at the organization level.","requestBody":{"content":{"application/json":{"schema":{"description":"A record of usernames to add to the denylist, specifying replacements if they are already in use","type":"object","log_field":true,"additionalProperties":{"description":"The replacement username if the username is already in use","$ref":"#/components/schemas/Username"}}}},"description":"A record of usernames to add to the denylist, specifying replacements if they are already in use"},"parameters":[{"schema":{"type":"string"},"in":"header","name":"x-m2-organization-id","required":true,"description":"The ID of an organization"}],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"204":{"description":"Default Response","content":{"application/json":{"schema":{}}}},"207":{"description":"The response of adding usernames to the denylist and replacing if needed, in case some couldn't be added","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostUsernamesDenylistResponse"}}}}}},"delete":{"operationId":"deleteUsernamesDenylist","summary":"Delete usernames from the denylist","tags":["Profile"],"description":"This endpoint removes the provided list of usernames from the denylist.\nIf a username is in use and therefore cannot be removed from the denylist, it is skipped and returned as part of the response.\n\nImportant note: denylists rely on unique usernames being enforced at the organization level.","requestBody":{"content":{"application/json":{"schema":{"description":"An array of usernames to remove from the denylist","type":"array","items":{"type":"string"},"log_field":true}}},"description":"An array of usernames to remove from the denylist"},"parameters":[{"schema":{"type":"string"},"in":"header","name":"x-m2-organization-id","required":true,"description":"The ID of an organization"}],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"The response of deleting usernames from the denylist","content":{"application/json":{"schema":{"description":"The response of deleting usernames from the denylist","type":"object","properties":{"usernamesDeleted":{"type":"array","items":{"description":"An array of usernames that were removed from the denylist","type":"string"}},"usernamesInUse":{"type":"array","items":{"description":"An array of usernames that are in use and cannot be removed","type":"string"}}},"required":["usernamesDeleted","usernamesInUse"]}}}},"207":{"description":"The response of deleting usernames from the denylist","content":{"application/json":{"schema":{"description":"The response of deleting usernames from the denylist","type":"object","properties":{"usernamesDeleted":{"type":"array","items":{"description":"An array of usernames that were removed from the denylist","type":"string"}},"usernamesInUse":{"type":"array","items":{"description":"An array of usernames that are in use and cannot be removed","type":"string"}}},"required":["usernamesDeleted","usernamesInUse"]}}}}}}},"/username/denylist/":{"put":{"operationId":"setUsernamesDenylist","summary":"Overwrite the list of denylisted usernames","tags":["Profile"],"description":"This endpoint replaces the current denylist with the provided list of usernames.\nIf the operation cannot be completed due to some usernames already being in use, the response will contain a list of those usernames.\nIn this case, the denylist will not be modified, and an admin can first overwrite the usernames being used (see the POST api/profile/deny endpoint), and then try again.\n\nNone of the usernames in the request need to obey the restrictions regarding length and allowed characters.\n\nImportant note: denylists rely on unique usernames being enforced at the organization level.","requestBody":{"content":{"application/json":{"schema":{"description":"An array of usernames to add to the denylist","type":"array","items":{"type":"string"}}}},"description":"An array of usernames to add to the denylist"},"parameters":[{"schema":{"type":"string"},"in":"header","name":"x-m2-organization-id","required":true,"description":"The ID of an organization"}],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"204":{"description":"Default Response","content":{"application/json":{"schema":{}}}},"409":{"description":"The response of adding usernames to the denylist in case some are already in use","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PutUsernamesDenylistResponse"}}}}}}}},"servers":[{"url":"https://{organizationId}.m2worlds.io/api/profile","variables":{"organizationId":{"default":"your-organization-id"}}}],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}]}