# Builderly API reference

Base URL: http://hristovtintdetailng.com
Generated from the running server on 2026-11-09T17:13:29.278Z. Every mounted route is listed with the access it needs, the parameters its handler reads and the data models it uses.

## Authentication

Send `Authorization: Bearer <token>` where a route needs a token. Add `?ionic=true` to get JSON from routes that also render pages.

- **Admin token** (`admin`): Bearer token of a site admin (Authorization: Bearer <token>).
- **User token** (`user`): Bearer token of a signed-in user of the site.
- **Optional user** (`optional-user`): Works without a token; a user token personalises the answer.
- **User with access** (`user-priv`): A signed-in user whose plan grants access to the item.
- **Page access** (`page-priv`): Pages limited to some users check the token when one is sent.
- **Webhook signature** (`webhook`): Called by a provider; verified by its signature.
- **reCAPTCHA** (`recaptcha`): Needs a reCAPTCHA token from the site form.
- **System** (`system`): Internal - called by the platform itself.

### For AI assistants: getting a token

Public endpoints (Access: Public) need no token. Everything else - changing the site, or reading its orders, bookings, customers and other private data - needs the site owner's API token.

You cannot create a token yourself, and you must not ask for the owner's password. Ask the user for a token instead - you can send them this message as it is:

> To work with your site through its API, I need an API token from you:
> 1. Sign in to your Builderly admin: https://admin.max-media.io
> 2. Open Developers > API reference (or go straight to https://admin.max-media.io/tabs/site-builder/api-docs).
> 3. Press "Generate token", copy the token and paste it here.
> The token acts as you, so only share it in this chat. You can cancel it at any time by signing out of all devices.

Then send it with every request as `Authorization: Bearer <token>`, and add `?ionic=true` to get JSON. Calls go to the site's own address (its domain), not to the reference's.

The token acts as the user: say what you will change and wait for their yes before any request that creates, changes or deletes something, never repeat the token back, and never put it in a link or a file you share.

## Status codes

| Code | Name | Meaning |
| --- | --- | --- |
| 200 | OK | It worked. The answer is the object or list asked for. |
| 201 | Created | The object was created. Some endpoints send it back; others send an empty body. |
| 202 | Accepted | The work was started and finishes in the background - for example a video being processed ({ "status": "processing" }). Check back on the object. |
| 204 | No Content | It worked, and there is nothing to send back - for example after removing a staff member. |
| 301 | Moved Permanently | The address changed; follow the Location header. |
| 400 | Bad Request | The request was refused as sent: a required field is missing, a value has the wrong type or fails validation. The body says what - often as plain text. |
| 401 | Unauthorized | No token, or one that is invalid or signed out. Without ?ionic=true, some endpoints answer this with the HTML login page instead of JSON. |
| 402 | Payment Required | The content needs a subscription: the user has no price plan that unlocks it. |
| 403 | Forbidden | The token is valid but may not do this - the record belongs to someone else, or the user is not an admin. AI builder endpoints also answer 403 when the account is out of credits. |
| 404 | Not Found | No object with that ID or URL slug, or no such endpoint. |
| 409 | Conflict | It clashes with the current state: the item is already being processed, a version is already applied, or an AI plan or preview is no longer available. |
| 410 | Gone | It existed but is no longer there - for example a comment already deleted on the social network. |
| 412 | Precondition Failed | A rule the request must meet is not met - for example push notifications of the same type at least 48 hours apart. |
| 418 | I'm a teapot | An account confirmation or password reset link was used with an email that does not match it. |
| 421 | Misdirected Request | The domain is not a Builderly site. Call the site's own address. |
| 422 | Unprocessable Content | The request was understood but could not be done - for example the AI could not read the website it was asked to clone. The message says what to try instead. |
| 429 | Too Many Requests | Slow down: the site's request limit was reached, an AI chat already has a request running, or the hourly limit of AI search answers is used up. Wait and retry. |
| 500 | Internal Server Error | Something failed on the server. Retrying later may work; if it keeps failing, the request may be one the endpoint does not handle. |
| 502 | Bad Gateway | A service the request depends on failed - for example the address a redirect forwards to. |
| 503 | Service Unavailable | Used by the lead form when an order is below its minimum value, not only for outages: read the message. |

Errors do not share one shape: depending on the endpoint the body is plain text, { "error": "..." }, { "message": "..." } or empty. Rely on the status code, and show the body to the user as the reason.

## Endpoints

### Community

Community is the social side of the site: posts, comments, ratings, groups and messages between users, when social mode is on.

#### Comment

##### Like or unlike a comment
`PATCH /comment-like/:id`
Likes or unlikes a comment and notifies its author. Calling it again takes the like back. Answers the comment's likes.
- Access: User token
- Path:
  - `id` (string): The ID of the comment.
- Body:
  - `liked_by_id` (string): The comment's liked by id.
  - `action` (string): The comment's action.
  - `liked_by` (string): The comment's liked by.
- Returns: the Comment object.
- Status codes: 200, 401, 404, 500
- Models: Comment, ConnectedAccount, Post, Product, Service, BlogPost, Program, UserEngagementNotification

##### List all comments
`GET /comments`
Every comment. Every comment on the site.
- Access: User token
- Returns: a list of Comment objects.
- Status codes: 200, 401, 500
- Models: Comment

##### Create a comment
`POST /comments`
Comments on a post, product, service or other record (commented_on) and notifies its owner and mentions. Answers 201 with no body. 403 "Comment limit exeded." when the user comments too often; 401 when posting for an account they may not act for. Counts as an interaction on a post, which feeds its ranking.
- Access: User token
- Body:
  - `user` (objectid): User.id.
  - `comment` (string): Comment message.
  - `commented_on` (objectid): Id of the record commented on (a post, product, service...).
  - `mentions` (objectid[]): User ids.
  - `connected_account_user` (objectid): User.id.
- Returns: the Comment object.
- Status codes: 201, 400, 401, 403, 500
- Models: ConnectedAccount, User, MyContact, Product, Service, BlogPost, Post, Program, Video, SocialModeSettings, UserEngagementNotification, Comment

##### Update the comment
`PATCH /comments`
Edits a comment (comment_id, comment) and notifies new mentions. Only the comment's author (401 otherwise). Answers the updated comment; only users newly mentioned are notified.
- Access: User token
- Body:
  - `comment_id` (string): The comment's comment id.
  - `comment` (string): Comment message.
  - `mentions` (objectid[]): User ids.
- Returns: the Comment object.
- Status codes: 200, 400, 401, 404, 500
- Models: Comment, UserEngagementNotification

##### Update the comments add reply
`PATCH /comments-add-reply`
Replies to a comment and notifies its author and mentions. Answers { reply }: the new reply. 403 when replying for an account the user may not act for.
- Access: User token
- Body:
  - `comment_id` (string): The comments add reply's comment id.
  - `comment` (string): The comments add reply's comment.
  - `user_id` (string): The comments add reply's user id.
  - `mentions` (string): The comments add reply's mentions.
- Status codes: 200, 400, 401, 403, 404, 500
- Models: Comment, ConnectedAccount, User, Post, Product, Service, BlogPost, Program, UserEngagementNotification

##### Retrieve a comments of
`GET /comments-of/:id`
Comments on a record. 404 when there are none.
- Access: User token
- Path:
  - `id` (string): The ID of the comments of.
- Status codes: 200, 401, 404, 500
- Models: Comment

##### Retrieve a comments on
`GET /comments-on/:id&:skip`
Comments on a record, a page at a time, without restricted users. Answers { comments, count }, newest first then most liked, skipping users the viewer blocked or who blocked them.
- Access: User token
- Path:
  - `id` (string): The ID of the comments on.
  - `skip` (string): How many results to skip - for paging.
- Status codes: 200, 401, 404, 500
- Models: Comment

##### Update the comments reply
`PATCH /comments-reply`
Edits a reply to a comment and notifies new mentions. Only the reply's author (401 otherwise). Answers { reply }.
- Access: User token
- Body:
  - `comment_id` (string): The comments reply's comment id.
  - `index` (string): The comments reply's index.
  - `comment` (string): The comments reply's comment.
  - `mentions` (string): The comments reply's mentions.
- Status codes: 200, 400, 401, 404, 500
- Models: Comment, UserEngagementNotification

##### Delete a comments reply
`DELETE /comments-reply/:id/:index`
Deletes a reply to a comment. index is the reply's position in the comment's replies. Only its author or the owner of what it is on (403 otherwise).
- Access: User token
- Path:
  - `id` (string): The ID of the comments reply.
  - `index` (string): The comments reply's index.
- Returns: an empty answer on success.
- Status codes: 200, 401, 404, 500
- Models: Comment, ConnectedAccount

##### Retrieve a comment
`GET /comments/:id`
One comment. 404 when there is no such comment.
- Access: User token
- Path:
  - `id` (string): The ID of the comment.
- Returns: the Comment object.
- Status codes: 200, 401, 404, 500
- Models: Comment

##### Delete a comment
`DELETE /comments/:id`
Deletes a comment (its author, or the owner of what it is on). Answers the deleted comment; 403 for anyone else.
- Access: User token
- Path:
  - `id` (string): The ID of the comment.
- Returns: an empty answer on success.
- Status codes: 200, 401, 404, 500
- Models: Comment, Post, ConnectedAccount

##### Update a hide comment
`PATCH /hide-comment/:id&:reply`
Hides a comment on a post, or one of its replies (reply: its position), for the post's author. Only the post's author can hide; for anyone else nothing changes. A hidden comment stays stored but others no longer see it. There is no way to show it again here.
- Access: User token
- Path:
  - `id` (string): The ID of the hide comment.
  - `reply` (string): The hide comment's reply.
- Returns: the Comment object.
- Status codes: 200, 400, 401, 404, 500
- Models: Comment, Post

##### Like or unlike a reply
`PATCH /reply-like/:id&:replyId`
Likes or unlikes a reply and notifies its author. Calling it again takes the like back. Answers the reply's likes.
- Access: User token
- Path:
  - `id` (string): The ID of the reply.
  - `replyId` (string): The reply's reply id.
- Body:
  - `liked_by_id` (string): The reply's liked by id.
  - `action` (string): The reply's action.
  - `liked_by` (string): The reply's liked by.
- Status codes: 200, 401, 404, 500
- Models: Comment, ConnectedAccount, Post, Product, Service, BlogPost, Program, UserEngagementNotification

##### List all user comments
`GET /user-comments/:skip`
Comments the signed-in user wrote, with what they are on. Answers the comments grouped by what they are on: posts, products, services, blog posts. 403 for an account the user may not act for.
- Access: User token
- Path:
  - `skip` (string): How many results to skip - for paging.
- Query:
  - `on_behalf_of` (string): Only user comments with this on behalf of.
- Returns: a list of Comment objects.
- Status codes: 200, 401, 403, 500
- Models: ConnectedAccount, User, Comment, Post, Product, Media, Service, BlogPost

##### List all user liked comments
`GET /user-liked-comments/:skip`
Comments the signed-in user liked. Comments and replies together, with count.
- Access: User token
- Path:
  - `skip` (string): How many results to skip - for paging.
- Query:
  - `on_behalf_of` (string): Only user liked comments with this on behalf of.
- Returns: a list of Comment objects.
- Status codes: 200, 401, 403, 500
- Models: ConnectedAccount, User, Comment, Post, Product, Service, BlogPost

#### Group

##### Update the group remove user
`PATCH /group-remove-user`
Removes a user from a group (group, user). Only the group's owner.
- Access: User token
- Body:
  - `group` (string): The group remove user's group.
  - `user` (string): The group remove user's user.
- Status codes: 200, 400, 401, 403, 404, 500
- Models: Group, GroupJoinRequest

##### Retrieve a group
`GET /group/:id`
Opens a group in the app (redirects to its app page). For links shared from the app: the website sends the visitor to the group in the app.
- Access: Optional user
- Path:
  - `id` (string): The ID of the group.
- Status codes: 200, 500
- Models: MyContact

##### Create a group
`POST /groups`
Creates a group. 403 when the site does not let this user create groups. Answers 201 with the group.
- Access: User token
- Returns: the Group object.
- Status codes: 201, 400, 401, 403, 500
- Models: SocialModeSettings, Group

##### Retrieve a group
`GET /groups/:id`
One group with the user's membership. 402 when the group needs a subscription the user lacks; 404 when there is no such group.
- Access: User token
- Path:
  - `id` (string): The ID of the group.
- Returns: the Group object.
- Status codes: 200, 401, 402, 404, 500
- Models: SocialModeSettings, Group, GroupJoinRequest

##### Update a group
`PATCH /groups/:id`
Updates a group. Fields outside the allowed list are silently ignored. Answers the updated record, or 404.
- Access: User token
- Path:
  - `id` (string): The ID of the group.
- Returns: the Group object.
- Status codes: 200, 400, 401, 403, 404, 500
- Models: Group

##### Delete a group
`DELETE /groups/:id`
Deletes a group. Only its owner (403 otherwise). Its posts are deleted with it.
- Access: User token
- Path:
  - `id` (string): The ID of the group.
- Returns: an empty answer on success.
- Status codes: 200, 401, 403, 404, 500
- Models: Group, Post, Comment, Media, User

##### List all groups
`GET /groups/:skip/:limit`
Groups, the most active first, a page at a time. Answers { groups, count }.
- Access: Public
- Path:
  - `skip` (string): How many results to skip - for paging.
  - `limit` (string): How many results to return.
- Returns: a list of Group objects.
- Status codes: 200, 500
- Models: Group

##### Join a join group
`POST /join-group`
Joins a group, or asks to join a private one (group). Answers 201 { group_join_request }: 'accepted' for a public group, 'pending' for a private one until its owner answers. 403 when a request is already pending.
- Access: User token
- Body:
  - `group` (string): The join group's group.
- Returns: the Group object.
- Status codes: 201, 400, 401, 403, 404, 500
- Models: Group, GroupJoinRequest, UserEngagementNotification

##### List all groups
`GET /my-groups`
Groups the signed-in user is in, with their join requests. Answers { my_groups, joined_groups, canCreateGroups }.
- Access: User token
- Returns: a list of Group objects.
- Status codes: 200, 401, 500
- Models: Group, GroupJoinRequest

##### List all groups
`GET /search-groups/:args/:skip`
Groups whose name matches the words. Nine at a time.
- Access: Public
- Path:
  - `args` (string): The group's args.
  - `skip` (string): How many results to skip - for paging.
- Returns: a list of Group objects.
- Status codes: 200, 404, 500
- Models: Group

##### Update a join request with AI
`PATCH /update-join-request-status`
Accepts or refuses a request to join a group. Only the group's owner. Answers 201.
- Access: User token
- Body:
  - `group` (objectid): Group.id the user asks to join.
  - `user` (objectid): User.id.
- Returns: the GroupJoinRequest object.
- Status codes: 201, 400, 401, 403, 404, 500
- Models: Group, GroupJoinRequest, UserEngagementNotification

#### Message

##### Add an add user
`PATCH /add-user/:id`
Adds users to a group conversation (users) and notifies them. Answers 201.
- Access: User token
- Path:
  - `id` (string): The ID of the add user.
- Body:
  - `users` (string): The add user's users.
- Status codes: 201, 400, 401, 404, 500
- Models: Message

##### Connect a connect to room
`POST /connect-to-room`
Opens or joins the conversation between the signed-in user and another user or group. Answers 201 with the conversation (its room for the live connection), creating it the first time. 403 when the ids sent do not match the signed-in user.
- Access: User token
- Body:
  - `me` (string): The connect to room's me.
  - `chatSupport` (string): The connect to room's chat support.
  - `receiver_id` (string): The connect to room's receiver id.
  - `user` (string): The connect to room's user.
  - `room` (string): The connect to room's room.
- Status codes: 201, 400, 401, 403, 500
- Models: ConnectedAccount, User, Message

##### Update a delete chat
`PATCH /delete-chat/:id`
Deletes a conversation for the signed-in user only. The other members keep the conversation and its messages.
- Access: User token
- Path:
  - `id` (string): The ID of the delete chat.
- Body:
  - `user_id` (string): The delete chat's user id.
- Status codes: 200, 401, 403, 404, 500
- Models: Message, ConnectedAccount

##### Find a chat
`GET /find-chat/:product_id`
The conversation with a product's seller, to ask about it. Answers { url } of the conversation in the app, or {} when there is none yet.
- Access: User token
- Path:
  - `product_id` (string): The chat's product id.
- Status codes: 200, 401, 500
- Models: Message, MyContact

##### Leave a leave group
`PATCH /leave-group/:id`
Leaves a group conversation. Earlier messages stay in the group. Answers 201.
- Access: User token
- Path:
  - `id` (string): The ID of the leave group.
- Status codes: 201, 400, 401, 404, 500
- Models: Message

##### Retrieve a message event
`GET /message-event/:id`
A conversation's live events stream. 403 when the user is not in the conversation.
- Access: User token
- Path:
  - `id` (string): The ID of the message event.
- Status codes: 200, 401, 403, 404, 500
- Models: Message, ConnectedAccount

##### Update the message seen
`PATCH /message-seen`
Marks a conversation as read by the signed-in user. Answers { room }.
- Access: User token
- Body:
  - `id` (string): The ID of the message seen.
  - `user` (string): The message seen's user.
- Status codes: 200, 400, 401, 500
- Models: Message

##### List all messages
`GET /messages`
The signed-in user's conversations. The most recently active first.
- Access: User token
- Returns: a list of Message objects.
- Status codes: 200, 401, 500
- Models: Message

##### Create a message
`POST /messages`
Creates a conversation. 403 "Message lenght limit exceeded!" for a message over the length limit. Answers 201 with the message.
- Access: User token
- Body:
  - `message` (object[]): Message.
  - `product_id` (objectid): Product.id of product, that the message is about.
  - `receiver_id` (objectid): User.id of receiver.
  - `service_id` (objectid): Service.id.
  - `blogpost_id` (objectid): BlogPost.id.
  - `program_id` (objectid): Program.id.
  - `isDirectMessage` (boolean): Between two users, not in a group.
  - `postId` (string): The message's post id.
  - `group_users` (objectid[]): Keeps the messages after user leaves the group.
  - `isGroup` (boolean): A group conversation.
- Returns: the Message object.
- Status codes: 201, 400, 401, 403, 500
- Models: User, Service, Product, BlogPost, Program, Message

##### Retrieve a messages media
`GET /messages-medias/:id&:skip&:limit`
Pictures and files shared in a conversation, a page at a time. Answers { limitedPosts, limitedMedia, count }: shared posts and files.
- Access: User token
- Path:
  - `id` (string): The ID of the messages media.
  - `skip` (string): How many results to skip - for paging.
  - `limit` (string): How many results to return.
- Status codes: 200, 401, 404, 500
- Models: Message

##### Update a message
`PATCH /messages/:id`
Updates a conversation. Answers the updated conversation, or 404. Fields outside the allowed list are ignored.
- Access: User token
- Path:
  - `id` (string): The ID of the message.
- Returns: the Message object.
- Status codes: 200, 400, 401, 404, 500
- Models: Message

##### Delete a message
`DELETE /messages/:id`
Deletes a conversation. Deletes the whole conversation for everyone, with no check of who asks beyond being signed in. Answers it, or 404.
- Access: User token
- Path:
  - `id` (string): The ID of the message.
- Returns: an empty answer on success.
- Status codes: 200, 401, 404, 500
- Models: Message

##### Retrieve a message
`GET /messages/:id&:skip&:limit`
Messages of a conversation, a page at a time. Counted from the newest message. 404 when there is no such conversation.
- Access: User token
- Path:
  - `id` (string): The ID of the message.
  - `skip` (string): How many results to skip - for paging.
  - `limit` (string): How many results to return.
- Returns: the Message object.
- Status codes: 200, 401, 404, 500
- Models: Message

##### Retrieve a received in app message
`GET /received-in-app-message/:id`
One in-app notification, with its group. With who sent it and the post it is about.
- Access: Public
- Path:
  - `id` (string): The ID of the received in app message.
- Status codes: 200, 400, 404, 500
- Models: UserEngagementNotification, Group

##### Send an in app message
`POST /send-in-app-message`
Sends an in-app notification to users. Answers 201 { room, notification_id }. 500 "Notification already send." when the same notification was already sent.
- Access: User token
- Body:
  - `type` (string): The in app message's type.
  - `comment_owner` (string): The in app message's comment owner.
  - `item_id` (string): The ID of the in app message to change.
  - `action_doer` (string): The in app message's action doer.
  - `group` (string): The in app message's group.
  - `owner_id` (string): The in app message's owner id.
  - `from` (string): The in app message's from.
  - `message` (string): The in app message's message.
  - `mentioned` (string): The in app message's mentioned.
  - `post` (string): The in app message's post.
- Status codes: 201, 400, 401, 500
- Models: UserEngagementNotification

##### Send a message
`POST /send-message`
Sends a message in a conversation and notifies its members. Answers 201 with the sent message. Every other member gets a push notification. 403 when the sender may not write there.
- Access: User token
- Body:
  - `from` (string): The message's from.
  - `text` (string): The message's text.
  - `chatSupport` (string): The message's chat support.
  - `receiver_id` (objectid): User.id of receiver.
  - `to` (string): The message's to.
  - `room` (string): The message's room.
  - `isDirectMessage` (boolean): Between two users, not in a group.
  - `postId` (string): The message's post id.
  - `userId` (string): The message's user id.
  - `groupId` (string): The message's group id.
  - `medias` (string): The message's medias.
- Returns: the Message object.
- Status codes: 201, 400, 401, 403, 500
- Models: ConnectedAccount, User, Message, BlogPost, Service, Product, UserEngagementNotification

##### Delete a sent message
`DELETE /sent-message/:id&:msg`
Deletes one of the signed-in user's messages. msg is the message's id inside the conversation.
- Access: User token
- Path:
  - `id` (string): The ID of the sent message.
  - `msg` (string): The sent message's msg.
- Returns: an empty answer on success.
- Status codes: 200, 401, 404, 500
- Models: Message

##### Update the user added
`PATCH /user-added`
Adds the signed-in user to a group conversation. Answers { room }. 403 when the user was not invited.
- Access: User token
- Body:
  - `room` (string): The user added's room.
  - `users` (string): The user added's users.
- Status codes: 200, 400, 401, 403, 500
- Models: Message, ConnectedAccount, User

#### Partner

##### List all partners
`GET /partners`
Get partners, optionally searched, filtered, sorted and paged. Renders the locations page; JSON with ?ionic. Search, category filters, sorting and paging come from the query.
- Access: Optional user
- Status codes: 200, 500

##### Create a partner
`POST /partners`
Creates a location or partner. Answers 201 with the location.
- Access: Admin token
- Returns: the Partner object.
- Status codes: 201, 400, 401, 500
- Models: Partner

##### Retrieve a partner
`GET /partners/:id`
One location or partner. With its venue types. 404 when there is no such location.
- Access: Public
- Path:
  - `id` (string): The ID of the partner.
- Returns: the Partner object.
- Status codes: 200, 404, 500
- Models: Partner

##### Update a partner
`PATCH /partners/:id`
Updates a location or partner. Answers the location, or 404.
- Access: Admin token
- Path:
  - `id` (string): The ID of the partner.
- Body:
  - `address` (string): Street address.
  - `city` (string): City.
  - `country` (string): Not required - records created before the split still carry the country inside city, and forcing it would reject every update to them.
- Returns: the Partner object.
- Status codes: 200, 400, 401, 404, 500
- Models: Partner

##### Delete a partner
`DELETE /partners/:id`
Deletes a location or partner. Answers the deleted location, or 404.
- Access: Admin token
- Path:
  - `id` (string): The ID of the partner.
- Returns: an empty answer on success.
- Status codes: 200, 401, 404, 500
- Models: Partner

#### Post

##### Retrieve the avg cost per action
`GET /avg-cost-per-action`
The average cost per action of ads with a given targeting (?interests, ?languages, ?keywords...). Answers { cost_per_click, cost_per_mile } from earlier ads with a similar targeting, to estimate a boost.
- Access: User token
- Query:
  - `interests` (string): Only avg cost per actions with this interests.
  - `app_categories` (string): Only avg cost per actions with this app categories.
  - `languages` (string): Only avg cost per actions with this languages.
  - `keywords` (string): Only avg cost per actions with this keywords.
  - `user_economics` (string): Only avg cost per actions with this user economics.
  - `user_education` (string): Only avg cost per actions with this user education.
  - `marital_status` (string): Only avg cost per actions with this marital status.
  - `ages` (string): Only avg cost per actions with this ages.
  - `sexes` (string): Only avg cost per actions with this sexes.
- Status codes: 200, 401, 500
- Models: Post

##### List all bites
`GET /bites/:posts&:popular&:ads&:location_ads`
The short video feed by the user's interests, with ads. Answers { posts, length, location_ads_skip, ads_skip }. Cached per user for 5 minutes.
- Access: User token
- Path:
  - `posts` (string): The bite's posts.
  - `popular` (string): The bite's popular.
  - `ads` (string): The bite's ads.
  - `location_ads` (string): The bite's location ads.
- Status codes: 200, 401, 500
- Models: Post

##### Update a boost user post
`PATCH /boost-user-post/:id`
Boosts a post as an ad with its targeting, or edits a boost (?edit). The boost is paid from the user's wallet: 400 "Insufficient funds." when it does not cover the budget. Answers the post.
- Access: User token
- Path:
  - `id` (string): The ID of the boost user post.
- Query:
  - `on_behalf_of` (string): Only boost user posts with this on behalf of.
  - `edit` (string): Only boost user posts with this edit.
- Body:
  - `interests` (string[]): From Google Segments.
  - `app_categories` (string): The boost user post's app categories.
  - `languages` (string): The boost user post's languages.
  - `keywords` (string[]): Words it is found by.
  - `user_economics` (string): Low, middle, high.
  - `user_education` (string): Low, middle, high.
  - `marital_status` (string): Single, married.
  - `ages` (string): The boost user post's ages.
  - `sexes` (string): The boost user post's sexes.
  - `cost_per_click` (string): The boost user post's cost per click.
  - `cost_per_mile` (string): The boost user post's cost per mile.
  - `created_on` (string): The boost user post's created on.
  - `duration` (string): The boost user post's duration.
  - `days_left` (string): The boost user post's days left.
  - `daily_budget` (string): The boost user post's daily budget.
  - `outer_link` (string): The boost user post's outer link.
  - `targeting` (string): The boost user post's targeting.
  - `isAdvertisment` (boolean): A paid ad.
- Returns: the Post object.
- Status codes: 200, 400, 401, 403, 404, 500
- Models: Post, ConnectedAccount, User

##### List all boosted posts
`GET /boosted-posts`
The user's boosted posts with their pixel results, or those of an account they manage (?on_behalf_of). Newest boost first. 403 for an account the user may not act for.
- Access: User token
- Query:
  - `on_behalf_of` (string): Only boosted posts with this on behalf of.
- Returns: a list of Post objects.
- Status codes: 200, 401, 403, 500
- Models: ConnectedAccount, User, Post, PixelData

##### Update a boost user post
`PATCH /cancel-boost-user-post/:id`
Stops a post's boost. Answers { returnCredits }: the unspent budget returned to the wallet.
- Access: User token
- Path:
  - `id` (string): The ID of the boost user post.
- Query:
  - `on_behalf_of` (string): Only boost user posts with this on behalf of.
- Returns: the Post object.
- Status codes: 200, 400, 401, 403, 404, 500
- Models: Post, ConnectedAccount, User

##### List all expirable posts
`GET /expirable-posts/:skip&:feed&:users`
Stories from who the user follows.
- Access: User token
- Path:
  - `skip` (string): How many results to skip - for paging.
  - `feed` (string): The expirable post's feed.
  - `users` (string): The expirable post's users.
- Status codes: 200, 401, 500

##### List all explores
`GET /explore/:posts&:popular&:ads&:location_ads`
The explore feed: popular posts by the user's interests, with ads. Answers { posts, length, location_ads_skip, ads_skip }; send the skips back on the next call. Cached per user for 5 minutes.
- Access: User token
- Path:
  - `posts` (string): The explore's posts.
  - `popular` (string): The explore's popular.
  - `ads` (string): The explore's ads.
  - `location_ads` (string): The explore's location ads.
- Status codes: 200, 401, 500
- Models: Post

##### List all feeds
`GET /feed/:posts&:popular&:ads&:location_ads&:users`
The signed-in user's home feed: posts from who they follow and by their interests, popular posts and ads, skipping those already seen (counts in the path). The path carries how many posts, popular posts and ads of each kind the app already has, so each call answers the next ones. Cached per user for 5 minutes.
- Access: User token
- Path:
  - `posts` (string): The feed's posts.
  - `popular` (string): The feed's popular.
  - `ads` (string): The feed's ads.
  - `location_ads` (string): The feed's location ads.
  - `users` (string): The feed's users.
- Status codes: 200, 401, 500
- Models: GroupJoinRequest, Post, Comment

##### List all following suggestions
`GET /following-suggestions`
Users to follow, by the signed-in user's interests. Ten users, with the interests they were picked by.
- Access: User token
- Status codes: 200, 401, 500
- Models: User

##### List all group feeds
`GET /group-feed/:group/:skip/:limit`
A group's posts, when the user may see the group. Answers { posts, length }. A private group answers 401 until the user's join request is accepted, with group_join_request pending or rejected. Cached per user for 5 minutes.
- Access: User token
- Path:
  - `group` (string): The group feed's group.
  - `skip` (string): How many results to skip - for paging.
  - `limit` (string): How many results to return.
- Status codes: 200, 401, 500
- Models: Group, GroupJoinRequest, Post, Comment

##### Retrieve a long video avg percentage viewed insight
`GET /long-video-avg-percentage-viewed-insights/:id`
The average share of a long video that viewers watch. Answers { insights }.
- Access: User token
- Path:
  - `id` (string): The ID of the long video avg percentage viewed insight.
- Status codes: 200, 401, 500
- Models: Post, VideoInteraction

##### Retrieve a long video engagement insight
`GET /long-video-engagement-insights/:id`
Engagement of a long video: watch time against views, likes and comments. Answers { insights }.
- Access: User token
- Path:
  - `id` (string): The ID of the long video engagement insight.
- Status codes: 200, 401, 500
- Models: VideoInteraction, Post

##### Retrieve a long video total watchtime insight
`GET /long-video-total-watchtime-insights/:id`
Total watch time of a long video. Answers { insights }.
- Access: User token
- Path:
  - `id` (string): The ID of the long video total watchtime insight.
- Status codes: 200, 401, 500
- Models: VideoInteraction

##### Record a view of a long video days insight
`GET /long-video-views-by-days-insights/:id&:days`
Views of a long video per day over the last days. Answers { insights }: one entry per day.
- Access: User token
- Path:
  - `id` (string): The ID of the long video days insight.
  - `days` (string): The long video days insight's days.
- Status codes: 200, 401, 500
- Models: VideoInteraction

##### Retrieve a long video watchtime days insight
`GET /long-video-watchtime-by-days-insights/:id&:days`
Watch time of a long video per day over the last days. Answers { insights }: one entry per day.
- Access: User token
- Path:
  - `id` (string): The ID of the long video watchtime days insight.
  - `days` (string): The long video watchtime days insight's days.
- Status codes: 200, 401, 500
- Models: VideoInteraction

##### List all long videos
`GET /long-videos/:posts&:popular&:ads`
The long video feed by the user's interests, after ?current_video. Cached per user for 5 minutes.
- Access: User token
- Path:
  - `posts` (string): The long video's posts.
  - `popular` (string): The long video's popular.
  - `ads` (string): The long video's ads.
- Query:
  - `current_video` (string): Only long videos with this current video.
- Status codes: 200, 401, 500
- Models: Post

##### List all feeds
`GET /my-feed/:skip/:limit`
The signed-in user's own posts, a page at a time. Answers { posts, length }, newest first, each with what it is attached to (a product, a group...).
- Access: User token
- Path:
  - `skip` (string): How many results to skip - for paging.
  - `limit` (string): How many results to return.
- Status codes: 200, 401, 500
- Models: Post, Comment

##### List all videos
`GET /my-videos`
The signed-in user's video posts. Video posts only.
- Access: User token
- Status codes: 200, 401, 404, 500
- Models: Post

##### Update the pin group post
`PATCH /pin-group-post/:post/:group`
Pins or unpins a post in a group (the group's admin) and notifies its author. Answers { isPinned }. 403 when the user is not the group's admin.
- Access: User token
- Path:
  - `post` (string): The pin group post's post.
  - `group` (string): The pin group post's group.
- Returns: the Post object.
- Status codes: 200, 401, 403, 404, 500
- Models: Group, Post, UserEngagementNotification

##### List all post campaigns
`GET /post-campaigns`
The user's ad campaigns with their pixel results. Newest first. 403 for an account the user may not act for.
- Access: User token
- Query:
  - `on_behalf_of` (string): Only post campaigns with this on behalf of.
- Status codes: 200, 401, 403, 500
- Models: ConnectedAccount, User, Post, PixelData

##### Update the post comment
`PATCH /post-comments/:post&:comment`
Adds or removes a comment's reference on a post. Answers with no body.
- Access: User token
- Path:
  - `post` (string): The post comment's post.
  - `comment` (string): The post comment's comment.
- Status codes: 200, 400, 401, 500
- Models: Post

##### Update a post cta click
`PATCH /post-cta-clicks/:id`
Counts a click on a post's call-to-action. One per user.
- Access: User token
- Path:
  - `id` (string): The ID of the post cta click.
- Status codes: 200, 400, 401, 500
- Models: Post

##### Retrieve a post feed
`GET /post-feed/:posts&:popular&:ads&:original_post_id&:location_ads`
Posts to show after one post, by interests, with ads. Answers { posts, length, location_ads_skip, ads_skip }.
- Access: User token
- Path:
  - `posts` (string): The post feed's posts.
  - `popular` (string): The post feed's popular.
  - `ads` (string): The post feed's ads.
  - `original_post_id` (string): The post feed's original post id.
  - `location_ads` (string): The post feed's location ads.
- Status codes: 200, 401, 500
- Models: Post

##### Retrieve a post insight
`GET /post-insights/:id`
A post's insights: views, reach, likes, shares, saves and clicks over time. 403 when the post is not the user's or an account's they manage.
- Access: User token
- Path:
  - `id` (string): The ID of the post insight.
- Query:
  - `on_behalf_of` (string): Only post insights with this on behalf of.
- Status codes: 200, 401, 403, 500
- Models: ConnectedAccount, Post

##### Update a post poll
`PATCH /post-poll/:id`
Votes in a post's poll (answer), once per user. 403 "User already voted."
- Access: User token
- Path:
  - `id` (string): The ID of the post poll.
- Body:
  - `answer` (string): The post poll's answer.
- Status codes: 200, 400, 401, 403, 500
- Models: Post

##### Update a post reach
`PATCH /post-reach/:id`
Counts that a post reached the signed-in user. One per user.
- Access: User token
- Path:
  - `id` (string): The ID of the post reach.
- Status codes: 200, 400, 401, 500
- Models: Post

##### Update a post times showed
`PATCH /post-times-showed/:id`
Counts that a post was shown in a feed. Answers with no body.
- Access: User token
- Path:
  - `id` (string): The ID of the post times showed.
- Status codes: 200, 400, 401, 500
- Models: Post

##### Record a view of a post
`PATCH /post-views/:id`
Counts a view of a post by the signed-in user. One view per user. Counts as an interaction, which feeds its ranking.
- Access: User token
- Path:
  - `id` (string): The ID of the post.
- Returns: the Post object.
- Status codes: 200, 400, 401, 500
- Models: Post

##### Retrieve a post
`GET /post/:id`
Opens a post in the app (redirects to the app's post page). The website has no post page of its own; see /static-post for a shareable one.
- Access: Optional user
- Path:
  - `id` (string): The ID of the post.
- Status codes: 200, 500
- Models: MyContact

##### List all price plan posts
`GET /price-plan-posts/:skip`
Subscriber-only posts of creators the user subscribes to. Nine at a time, newest first, with each post's plans.
- Access: User token
- Path:
  - `skip` (string): How many results to skip - for paging.
- Returns: a list of Post objects.
- Status codes: 200, 401, 500
- Models: Subscription, Post

##### List all profile feeds
`GET /profile-feed/:user&:post&:skip`
A user's posts from one post on, for scrolling their profile. Answers { posts, length }.
- Access: User token
- Path:
  - `user` (string): The profile feed's user.
  - `post` (string): The profile feed's post.
  - `skip` (string): How many results to skip - for paging.
- Status codes: 200, 401, 500
- Models: Post

##### List all feeds
`GET /recent-feed/:skip&:users`
The newest posts, skipping banned users. Answers { posts, postCount }.
- Access: User token
- Path:
  - `skip` (string): How many results to skip - for paging.
  - `users` (string): The feed's users.
- Status codes: 200, 401, 500
- Models: Post

##### Remove a remove thread post
`PATCH /remove-thread-post/:post`
Takes a post out of its thread. Answers with no body.
- Access: User token
- Path:
  - `post` (string): The remove thread post's post.
- Returns: the Post object.
- Status codes: 200, 400, 401, 500
- Models: Post

##### List all saved posts
`GET /saved-posts`
Posts the signed-in user saved. With each post's plans, when it is subscriber-only.
- Access: User token
- Returns: a list of Post objects.
- Status codes: 200, 401, 500
- Models: Post, Comment

##### Create a sponsored post attribution
`POST /sponsored-post-attributions`
Attributes an ad interaction to a user (post_id, attributed_user_id). Charges the ad's budget for one click (or a thousand views) and credits 10% of that to the attributed user as revenue (see /user-attributions). Does nothing for a post that is not a running ad.
- Access: User token
- Body:
  - `post_id` (string): The sponsored post attribution's post id.
  - `attributed_user_id` (string): The sponsored post attribution's attributed user id.
- Status codes: 200, 401, 500
- Models: Post

##### Retrieve a static post
`GET /static-post/:id`
A post's shareable page, with its comments. For link previews and visitors without the app: a server-rendered page with the post's meta tags. Cached for an hour.
- Access: Public
- Path:
  - `id` (string): The ID of the static post.
- Returns: the Post object.
- Status codes: 200, 404, 500
- Models: Post, Comment

##### Retrieve a static profile
`GET /static-profile/:handle`
A user's shareable profile page, with their posts, products and services. Server-rendered with the profile's meta tags, for link previews. Cached for an hour.
- Access: Public
- Path:
  - `handle` (string): The static profile's handle.
- Status codes: 200, 404, 500
- Models: User, Post, Comment, Product, Service, BlogPost, PricePlan, Program, Subscription, Media

##### List all threads
`GET /threads/:skip&:users`
The threads feed: text posts from who the user follows and by interest. Answers { posts, length }.
- Access: User token
- Path:
  - `skip` (string): How many results to skip - for paging.
  - `users` (string): The thread's users.
- Status codes: 200, 401, 500
- Models: Post

##### List all trending videos
`GET /trending-videos/:category&:skip`
Trending videos in a category. Answers { posts, postCount }.
- Access: User token
- Path:
  - `category` (string): The trending video's category.
  - `skip` (string): How many results to skip - for paging.
- Status codes: 200, 401, 500
- Models: Post

##### Update the repost
`PATCH /update-repost/:post&:repost`
Adds a repost to a post's reposts. Answers with no body.
- Access: User token
- Path:
  - `post` (string): The repost's post.
  - `repost` (string): The repost's repost.
- Returns: the Post object.
- Status codes: 200, 400, 401, 500
- Models: Post

##### List all user exclusive feeds
`GET /user-exclusive-feed/:user/:skip/:limit`
A user's subscriber-only posts, when the visitor subscribes to them. Answers { posts, length }, newest first, with the plans that open them.
- Access: Optional user
- Path:
  - `user` (string): The user exclusive feed's user.
  - `skip` (string): How many results to skip - for paging.
  - `limit` (string): How many results to return.
- Status codes: 200, 500
- Models: Subscription, Post

##### List all user expirable posts
`GET /user-expirable-posts/:user`
A user's current stories, with what they are attached to. Newest first.
- Access: User token
- Path:
  - `user` (string): The user expirable post's user.
- Returns: a list of Post objects.
- Status codes: 200, 401, 500
- Models: Post, Program, Service, BlogPost, Product, Group

##### List all user feeds
`GET /user-feed/:user/:skip/:limit`
A user's posts that everyone may see, a page at a time. Answers { posts, length }, newest first. Subscriber-only posts are left out: see /user-exclusive-feed.
- Access: Optional user
- Path:
  - `user` (string): The user feed's user.
  - `skip` (string): How many results to skip - for paging.
  - `limit` (string): How many results to return.
- Status codes: 200, 500
- Models: Post, Comment

##### List all user group feeds
`GET /user-group-feed/:posts&:public_groups&:users`
Posts from the user's groups and public groups. Answers { posts, length }, newest first.
- Access: User token
- Path:
  - `posts` (string): The user group feed's posts.
  - `public_groups` (string): The user group feed's public groups.
  - `users` (string): The user group feed's users.
- Status codes: 200, 401, 500
- Models: Group, GroupJoinRequest, Post

##### List all user liked posts
`GET /user-liked-posts/:skip`
Posts the signed-in user liked, a page at a time. Answers { posts, postCount }. 403 for an account the user may not act for.
- Access: User token
- Path:
  - `skip` (string): How many results to skip - for paging.
- Query:
  - `on_behalf_of` (string): Only user liked posts with this on behalf of.
- Returns: a list of Post objects.
- Status codes: 200, 401, 403, 500
- Models: ConnectedAccount, User, Post

##### Retrieve a user long video ad
`GET /user-long-video-ads/:id`
Ads to show in a long video, by the viewer's interests and location. Ads by interest first, then by location.
- Access: Optional user
- Path:
  - `id` (string): The ID of the user long video ad.
- Status codes: 200, 404, 500
- Models: Post

##### Create a user post
`POST /user-post`
Publishes a post by the signed-in user (text, title, medias, poll, group), checks its pictures for explicit content and queues its videos for transcoding. 403 when the text or title is too long, 404 when the group does not exist. Pictures are checked for explicit content and given an AI caption; videos are queued for transcoding and the post fills in when they are ready.
- Access: User token
- Body:
  - `text` (string): The post's text.
  - `title` (string): The post's title.
  - `posted_in` (objectid): Group.id.
  - `selected_account_id` (string): The user post's selected account id.
  - `medias` (object[]): Pictures and videos of the post.
  - `exclusive` (boolean): Only for subscribers.
  - `mentions` (objectid[]): User ids.
  - `transcode` (string): The user post's transcode.
  - `link` (string): The user post's link.
- Returns: the Post object.
- Status codes: 201, 400, 401, 403, 404, 500
- Models: Group, GroupJoinRequest, ConnectedAccount, MyContact, Media, Message, UserEngagementNotification, Post

##### Like or unlike a user post
`PATCH /user-post-like/:id`
Likes, dislikes or takes back a reaction on a post, and notifies its author. Sending the same reaction again takes it back. Answers the post. Counts as an interaction, which feeds its ranking.
- Access: User token
- Path:
  - `id` (string): The ID of the user post.
- Body:
  - `likes` (objectid[]): User ids.
  - `dislikes` (objectid[]): User ids.
- Returns: the Post object.
- Status codes: 200, 400, 401, 404, 500
- Models: Post, UserEngagementNotification

##### Create a user post link
`POST /user-post-link-preview`
A link's preview for a post (link): its Open Graph title, picture and site name. The page is fetched by the server. Cached for an hour.
- Access: Optional user, User token
- Body:
  - `link` (string): The user post link's link.
- Status codes: 200, 401, 500

##### Retrieve a user post object
`GET /user-post-object/:id`
The product, service, post or program a post is attached to. 404 when there is no such post. Cached per user for 5 minutes.
- Access: Optional user
- Path:
  - `id` (string): The ID of the user post object.
- Status codes: 200, 404, 500
- Models: Post, Program, Service, BlogPost, Product

##### Save or unsave a user post
`PATCH /user-post-save/:id`
Saves or unsaves a post for the signed-in user. Calling it again unsaves. Answers the post.
- Access: User token
- Path:
  - `id` (string): The ID of the user post.
- Returns: the Post object.
- Status codes: 200, 400, 401, 404, 500
- Models: Post

##### Update a user post share
`PATCH /user-post-share/:id`
Records that the signed-in user shared a post (share). Answers the post.
- Access: User token
- Path:
  - `id` (string): The ID of the user post share.
- Body:
  - `share` (string): The user post share's share.
- Status codes: 200, 400, 401, 404, 500
- Models: Post

##### Retrieve a user post
`GET /user-post/:id`
One post with its comments and more posts to show after it. 404 when there is no such post. Cached for 5 minutes.
- Access: Optional user
- Path:
  - `id` (string): The ID of the user post.
- Returns: the Post object.
- Status codes: 200, 404, 500
- Models: Post, VideoInteraction

##### Update a user post
`PATCH /user-post/:id`
Edits a post of the signed-in user, or of an account they manage (?on_behalf_of), and notifies new mentions. 403 "Unauthorized" when the post is not the user's or an account's they manage. Answers the updated post.
- Access: User token
- Path:
  - `id` (string): The ID of the user post.
- Query:
  - `on_behalf_of` (string): Only user posts with this on behalf of.
- Body:
  - `mentions` (objectid[]): User ids.
- Returns: the Post object.
- Status codes: 200, 400, 401, 403, 404, 500
- Models: Post, ConnectedAccount, UserEngagementNotification

##### Delete a user post
`DELETE /user-post/:id`
Deletes a post with its comments and media (its author or the group's admin). Its comments and stored media are deleted with it. 403 when the user is neither its author nor the group's admin.
- Access: User token
- Path:
  - `id` (string): The ID of the user post.
- Returns: an empty answer on success.
- Status codes: 200, 401, 403, 404, 500
- Models: Post, Group, Comment, Media, User

##### Retrieve a video feed
`GET /video-feed/:video_id&:posts&:popular&:ads`
Videos to watch after a video, by the user's interests. Cached per user for 5 minutes.
- Access: User token
- Path:
  - `video_id` (string): The video feed's video id.
  - `posts` (string): The video feed's posts.
  - `popular` (string): The video feed's popular.
  - `ads` (string): The video feed's ads.
- Query:
  - `current_video` (string): Only video feeds with this current video.
- Status codes: 200, 401, 500
- Models: Post

##### List all viewed expirable posts
`GET /viewed-expirable-posts/:skip`
Stories the user has already seen.
- Access: User token
- Path:
  - `skip` (string): How many results to skip - for paging.
- Status codes: 200, 401, 500

#### Rating

##### Retrieve a rating
`GET /all-ratings/:id&:item&:skip&:limit`
An item's ratings page, a page at a time. Answers { ratings, count } in the app. 404 when the item does not exist.
- Access: Public
- Path:
  - `id` (string): The ID of the rating.
  - `item` (string): The rating's item.
  - `skip` (string): How many results to skip - for paging.
  - `limit` (string): How many results to return.
- Returns: the Rating object.
- Status codes: 200, 400, 404, 500
- Models: ProfessionalAccount, Service, Rating, Model, MyContact

##### Create a rating
`POST /rating`
Saves a rating with its pictures. Multipart with pictures. Reads no token: it comes from the rating email's page. Answers 201.
- Access: Public
- Body:
  - `body` (string): The rating's body.
- Returns: the Rating object.
- Status codes: 201, 400, 500
- Models: Media, Rating

##### Retrieve a rating
`GET /rating/:id`
One rating. Answers the rating.
- Access: User token
- Path:
  - `id` (string): The ID of the rating.
- Returns: the Rating object.
- Status codes: 200, 400, 401, 500
- Models: Rating

##### Retrieve the ratings table
`GET /ratings-table`
Ratings of one kind of item (?type), with the items. Newest first.
- Access: User token
- Query:
  - `charAt` (string): Only ratings tables with this char at.
  - `slice` (string): Only ratings tables with this slice.
  - `type` (string): Only ratings tables with this type.
- Status codes: 200, 400, 401, 500
- Models: Model, Rating

##### Retrieve a user rating
`GET /user-rating/:email&:validation_code&:type&:id`
The rating page from a rating email. A wrong code goes to the not-found page.
- Access: Public
- Path:
  - `email` (string): An email address.
  - `validation_code` (string): The user rating's validation code.
  - `type` (string): The user rating's type.
  - `id` (string): The ID of the user rating.
- Status codes: 200, 400, 500
- Models: Order, Booking, Service, Subscription, PricePlan, MyContact

## Objects

### BlogPost

An article on the site's blog.

- `title`: String, required - Title of blogpost.
- `url`: String, required - Generated from title, no need to set it manually.
- `static_url`: String - A fixed address kept when the post's url changes, so old links keep working.
- `header`: String - Short header of blogpost.
- `description`: String, required - Body text of blogpost.
- `medias`: Object[] - Attached media objects with ids.
  - `media`: ObjectId, → Media
  - `gcs_url`: String
  - `gcs_480_30_url`: String
  - `gcs_720_30_url`: String
  - `gcs_1080_30_url`: String
  - `duration`: Number
  - `thumbnail`: String
  - `vimeo_uri`: String
  - `vimeo_picture`: String
  - `vimeo_url`: String
  - `youtube_url`: String
  - `youtube_picture`: String
  - `_id`: ObjectId
- `published`: Boolean, default true - True if not set.
- `owner_id`: ObjectId, → User - User.id.
- `connected_account_owner_id`: ObjectId, → User - User.id.
- `collection_id`: ObjectId, → Collection - Collection, to which the blog post belongs.
- `selected`: Boolean, default false - False if not set.
- `custom_1`: String - Custom defined field 1.
- `custom_2`: String - Custom defined field 2.
- `custom_3`: String - Custom defined field 3.
- `about_page`: ObjectId, → AboutPage - Reference to AboutPage model, shown at the bottom of the post page.
- `suitability_price_plans`: ObjectId[], → PricePlan - A list of references to PricePlan model, marks post as suitable for users with those plans.
- `isSuitable`: Boolean - Set per request, not stored: whether the signed-in user's price plans match the post's suitability plans.
- `reference_id`: String - Id of the record the post was made from (an import or a clone).
- `wildcard_url`: Mixed - The wildcard route this post answers on, when it has one.
- `likes`: ObjectId[], → User - User ids.
- `views`: ObjectId[], → User - User ids.
- `total_views`: Number, default 0 - How many times the post was opened.
- `saves`: ObjectId[], → User - User ids.
- `times_showed`: Number, default 0 - How many times the post was shown in a list.
- `requiresLogin`: Boolean, default false - Only signed-in users can read the post.
- `requiresSubscription`: Boolean, default false - Only subscribers of the post's price plans can read it.
- `price_plan_ids`: String[] - A list of price plan id strings that grant access to this post.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Booking

One appointment a client booked for a service.

- `date`: String - Booking date.
- `date_iso`: Date - The booked date as an ISO string.
- `depart_date`: String - End date of a stay (date-range bookings).
- `depart_date_iso`: Date - End date as an ISO string.
- `price`: Number - What the booking costs.
- `time`: String - Booking time.
- `local_time`: String - The booked time in the customer's time zone.
- `isLastHour`: Boolean - The booking took the day's last free slot, so the day is marked fully booked.
- `organization_name`: String - For invoicing.
- `name`: String, required - Customer's full name.
- `firstname`: String - Customer's first name.
- `lastname`: String - Customer's last name.
- `email`: String, required - Customer's email.
- `phone_number`: String, required - Customer's phone number.
- `address`: String, required - Customer's address.
- `city`: String, required - Customer's city.
- `state`: String - Customer's state or region.
- `country`: String, required - Customer's country.
- `zip_code`: String, required - Customer's postal code.
- `tax_identification_number`: String - For invoicing.
- `notes`: String - What the customer wrote with the booking.
- `service_id`: ObjectId, → Service - Id of booked service.
- `staff_member`: ObjectId, → User - Booked staff member.
- `coupon`: ObjectId - Applied coupon.
- `discount_value`: Number, default 0 - Discount value of service with applied coupon.
- `finalized`: Boolean, default false - The booking went through (payment done or not needed).
- `confirmed`: Boolean, default false - The business confirmed the booking.
- `confirmed_timestamp`: Date - When it was confirmed.
- `week_reminder_sent`: Boolean - The reminder a week before was sent.
- `day_reminder_sent`: Boolean - The reminder a day before was sent.
- `status`: String - Follow-up outcome with the customer: other, churnet, not_upsell or upsell.
- `upsell`: ObjectId, → Order - Order.id.
- `staffmember_notes`: String - Notes the staff member keeps on the booking.
- `rating_mail_sent`: Boolean, default false - The email asking for a rating was sent.
- `call_attempts`: Number, default 0 - How many times the AI phone agent called about it.
- `last_call_attempt`: Date - When the last call was made.
- `attached_dynamic_models`: Object[] - Records of custom models attached to the booking.
  - `model`: ObjectId, → DynamicModel
  - `document`: ObjectId
  - `_id`: ObjectId
- `beds24_booking_id`: String - The booking's id in Beds24, when synced.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Comment

- `user`: ObjectId, required, → User - User.id.
- `connected_account_user`: ObjectId, → User - User.id.
- `commented_on`: ObjectId, required - Id of the record commented on (a post, product, service...).
- `comment`: String, required - Comment message.
- `likes`: ObjectId[], → User - User ids.
- `replies`: Object[] - Message.
  - `comment`: String, required
  - `user`: ObjectId, required, → User
  - `likes`: ObjectId[], → User
  - `createdAt`: Date
  - `isHidden`: Boolean, default false
  - `_id`: ObjectId
- `mentions`: ObjectId[], → User - User ids.
- `isHidden`: Boolean, default false - Hidden by a moderator; kept but not shown.
- `medias`: Object[] - Pictures attached to the comment.
  - `media`: ObjectId, → Media
  - `_id`: ObjectId
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### ConnectedAccount

- `on_behalf_of`: ObjectId, required, → User - The profile that gives authority to other user to alter his account.
- `user_account`: ObjectId, required, → User - The account which will receive certain privileges over over the account of the authorizer.
- `status`: String, default "pending" - State of the connection (connected, expired...).
- `is_authorized_to.create_posts`: Boolean, default false
- `is_authorized_to.send_messages`: Boolean, default false
- `is_authorized_to.answer_delete_comments`: Boolean, default false
- `is_authorized_to.access_engagements`: Boolean, default false
- `is_authorized_to.access_boosted_posts`: Boolean, default false
- `is_authorized_to.access_analytics`: Boolean, default false
- `is_authorized_to.alter_profile_settings`: Boolean, default false
- `is_authorized_to.catalogue_access.alter_products`: Boolean, default false
- `is_authorized_to.catalogue_access.alter_services`: Boolean, default false
- `is_authorized_to.catalogue_access.alter_blogposts`: Boolean, default false
- `is_authorized_to.catalogue_access.alter_price_plans`: Boolean, default false
- `is_authorized_to.catalogue_access.alter_programs`: Boolean, default false
- `is_authorized_to.catalogue_access.alter_orders`: Boolean, default false
- `is_authorized_to.catalogue_access.alter_bookings`: Boolean, default false
- `is_authorized_to.catalogue_access.alter_subscriptions`: Boolean, default false
- `is_authorized_to.catalogue_access.alter_purchases`: Boolean, default false
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Group

- `type`: String, required - Public / private;.
- `avatar`: ObjectId, → Media - Media.id.
- `cover`: ObjectId, → Media - Media.id.
- `name`: String, required - The group's name.
- `handle`: String, required - The group's unique @handle.
- `bio`: String - About the group.
- `participants`: ObjectId[], → User - User ids.
- `owner_id`: ObjectId, required, → User - User.id.
- `who_can_post`: String, default "all" - All, admin.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### GroupJoinRequest

- `group`: ObjectId, → GroupJoinRequest - Group.id the user asks to join.
- `user`: ObjectId, → User - User.id.
- `status`: String, default "pending" - Pending, rejected or accepted.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Media

An uploaded image, video or file.

- `file`: Buffer - (buffer) base64 image data.
- `file_path`: String - The bytes in Cloud Storage instead of `file` (utils/media-store.js): the object - named by the bytes' sha256, so identical pictures share one - and that hash.
- `alt`: String - Img alt (same as filename if not specified).
- `filename`: String - Name of the stored file.
- `filetype`: String - MIME type of the file.
- `vimeo_uri`: String - The video's Vimeo id, for videos hosted there.
- `vimeo_picture`: String - Thumbnail Vimeo made.
- `duration`: Number - Length of a video in seconds.
- `vimeo_url`: String - Link to the video on Vimeo.
- `youtube_url`: String - Link to the video on YouTube.
- `youtube_picture`: String - Thumbnail of the YouTube video.
- `thumbnail`: String - Small preview of the file.
- `gcs_url`: String - The file's address in cloud storage.
- `gcs_480_30_url`: String - The video transcoded to 480p.
- `gcs_720_30_url`: String - The video transcoded to 720p.
- `gcs_1080_30_url`: String - The video transcoded to 1080p.
- `picture_gcs_url`: String - The picture's address in cloud storage.
- `transcode_status`: String, default "not_started" - 'not_started' | 'pending' | 'error' | 'completed'.
- `owner_id`: ObjectId, → User - User id of owner.
- `sequence.status`: String
- `sequence.started_at`: Date
- `sequence.updated_at`: Date
- `sequence.step`: String
- `sequence.done`: Number
- `sequence.total`: Number
- `sequence.ext`: String
- `sequence.trim_start`: Number
- `sequence.trim_end`: Number
- `sequence.build_id`: String
- `sequence.previous_base`: String
- `sequence.frame_count`: Number
- `sequence.fps`: Number
- `sequence.width`: Number
- `sequence.height`: Number
- `sequence.desktop_path`: String
- `sequence.mobile_path`: String
- `sequence.portrait_path`: String
- `sequence.poster`: String
- `sequence.error`: String
- `source_url`: String - Site-clone real-asset reuse: the original URL this Media was downloaded from (asset-fetcher.js). Lets repeated/duplicate clone runs reuse the same stored asset instead of re-downloading it.
- `source_framing`: String - How a downloaded picture was prepared before it was stored (asset-fetcher.js FRAMING): a copy made before the frame its site baked in was taken off is not reused for one made after.
- `origin`: String - 'ai' for images the AI builder generated (validators.js). The site-readiness checklist counts the items still showing one, so people know which photos to replace with their own. Unset on uploads and on media created before it.
- `width`: Number - Displayed size of an image file (utils/image-size.js), so pages can give the <img> width/height and reserve its space before it loads. Set on save; older media by scripts/backfill-media-size.js.
- `height`: Number - Height of the picture in pixels.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Message

- `sender_id`: ObjectId, required, → User - User.id of sender is automatically set from auth.
- `receiver_id`: ObjectId, required, → User - User.id of receiver.
- `product_id`: ObjectId, → Product - Product.id of product, that the message is about.
- `service_id`: ObjectId, → Service - Service.id.
- `isOpened`: Boolean, default false - The recipient has read it.
- `blogpost_id`: ObjectId, → BlogPost - BlogPost.id.
- `isDirectMessage`: Boolean, default false - Between two users, not in a group.
- `message`: Object[] - Message.
  - `from`: ObjectId, required, → User
  - `text`: String, required
  - `createdAt`: String
  - `sent`: Boolean, default false
  - `seen`: Boolean, default false
  - `seen_by`: ObjectId[], → User
  - `postId`: ObjectId, → Post
  - `userId`: ObjectId, → User
  - `medias`: Object[]
    - `media`: ObjectId, → Media
    - `vimeo_uri`: String
    - `vimeo_picture`: String
    - `vimeo_url`: String
    - `youtube_url`: String
    - `youtube_picture`: String
    - `gcs_url`: String
    - `_id`: ObjectId
  - `isSystem`: Boolean, default false
  - `groupId`: ObjectId, → Group
  - `_id`: ObjectId
- `isGroup`: Boolean, default false - A group conversation.
- `group_users`: ObjectId[], → User - Keeps the messages after user leaves the group.
- `current_group_users`: ObjectId[], → User - Update when user leaves or joins.
- `users_nicknames`: Object[] - Nicknames members set for each other in the conversation.
  - `nickname`: String
  - `user`: ObjectId, → User
  - `_id`: ObjectId
- `group_avatar`: ObjectId, → Media - Media.id.
- `group_name`: String - Name of the group conversation.
- `delete_chat`: Object[] - Users who deleted the conversation for themselves, and when.
  - `isDeleted`: Boolean, default false
  - `user`: ObjectId, → User
  - `createdAt`: Date
  - `_id`: ObjectId
- `program_id`: ObjectId, → Program - Program.id.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Model

- `name`: String, required
- `make`: ObjectId, → Make
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### MyContact

The site's name and contact details.

- `zip_code`: String, required - Postal/ZIP code.
- `city`: String, required - The city where the business is located.
- `address`: String, required - The street address.
- `contact`: String - Html format.
- `email`: String, required - The public contact email address.
- `google_app`: String - Link to the business's app on Google Play.
- `workhours`: String - Opening hours as text.
- `logo`: ObjectId - Media.id.
- `site_name`: String, required - The business/site name shown publicly.
- `domain`: String, required - The site's own domain.
- `stock_domain`: String - The platform subdomain the site always answers on.
- `isMarket`: Boolean, required, default false - The site is a marketplace.
- `forbidden_collections`: Object[] - Array of {collection_id}.
  - `collection_id`: ObjectId, → Collection
  - `_id`: ObjectId
- `isInit`: Boolean, default false - The site was set up from a template.
- `template`: String, default "0000" - The template the site was made from.
- `lang`: String - 2-letter language code (e.g. "en", "fr", "de").
- `allowedComponents.services`: Boolean, default true
- `allowedComponents.products`: Boolean, default true
- `allowedComponents.blogposts`: Boolean, default true
- `allowedComponents.programs`: Boolean, default true
- `favicon`: ObjectId - Media.id of the browser tab icon.
- `cacheEnabled`: Boolean - Pages are cached for faster loading.
- `has_completed_startup_prompt`: Boolean, default true - The owner went through the first AI prompt.
- `gmb_location`: String - The Google Business Profile location linked to the site.
- `ga_property`: String - The Google Analytics property linked to the site.
- `site_generated_at`: Date - When the AI builder first built this site (a plan that made the homepage). Written once (runPlan); starts the admin's 15-minute launch offer.
- `admin_first_opened_at`: Date - When the owner first opened the admin; with admin_last_opened_at it tells "never opened it" from "opened it and left".
- `admin_last_opened_at`: Date - When the owner last opened the admin.
- `admin_in_app_browser`: Boolean - The owner last opened the admin inside an app's browser.
- `domain_suggestions`: Mixed - Domain names suggested to the owner, kept so they are not suggested again.
- `_id`: ObjectId

### Order

A completed purchase.

- `organization_name`: String - Customer's company name.
- `firstname`: String, required - Customer's first name.
- `lastname`: String, required - Customer's last name.
- `email`: String, required - Customer's email.
- `phone_number`: String, required - Customer's phone number.
- `address`: String, required - Delivery address.
- `city`: String, required - Delivery city.
- `state`: String - Delivery state or region.
- `country`: String, required - Delivery country.
- `zip_code`: String, required - Delivery postal code.
- `tax_identification_number`: String - Customer's tax number, for an invoice.
- `notes`: String - What the customer wrote with the order.
- `products`: String[] - Product ids ordered.
- `products_obj`: Object[] - The products ordered, as they were then: options, quantity and price.
  - `product_id`: ObjectId, → Product
  - `name`: String
  - `options`: String
  - `price`: Number
  - `quantity`: Number
  - `_id`: ObjectId
- `programs`: String[] - Program ids ordered.
- `programs_obj`: Object[] - The programs ordered, as they were then.
  - `program_id`: ObjectId, → Program
  - `title`: String
  - `price`: Number
  - `_id`: ObjectId
- `tickets`: ObjectId[], → Ticket - Ticket ids.
- `donations`: ObjectId[], → Donation - Donation ids.
- `donations_obj`: Object[] - The donations made with the order.
  - `donation_id`: ObjectId, → Donation
  - `name`: String
  - `options`: String
  - `price`: Number
  - `quantity`: Number
  - `_id`: ObjectId
- `value`: Number - Total of the order.
- `finalized`: Boolean, default false - Checkout was completed.
- `fulfilled`: Boolean, default false - The order was sent or handed over.
- `paid`: Boolean, default false - The order is paid.
- `delivery_method`: String - How it is delivered (courier, office, pickup...).
- `payment_method`: String - How it is paid (card, cash, invoice, PayPal).
- `shipping_cost`: Number - What delivery costs.
- `coupon_code`: String - The coupon used.
- `owner_id`: ObjectId, → User - User.id.
- `reference_id`: String - The order's id at the payment provider.
- `rating_mail_sent`: Boolean, default false - The email asking for a rating was sent.
- `shipping_label`: String - The courier's shipment label.
- `shipping_option`: String, one of address | office, default "address" - One of: address, office.
- `shipping_message`: String - The courier's last status message.
- `shipping_office`: String - The courier office it is delivered to.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Partner

A physical location or partner business, with its address and contacts.

- `name`: String, required - The location's or partner's name.
- `venue`: String - Deprecated, superseded by venue_types.
- `venue_types`: Object[] - [{ collection_id }] refs to 'partner/' Collections.
  - `collection_id`: ObjectId, → Collection
  - `_id`: ObjectId
- `city`: String, required - City.
- `country`: String - Not required - records created before the split still carry the country inside city, and forcing it would reject every update to them.
- `address`: String, required - Street address.
- `contact`: String - Contact person.
- `additional_information`: String - Anything else visitors should know.
- `phone`: String - Phone number.
- `email`: String - Email.
- `website`: String - Website.
- `hours`: String - Opening hours.
- `latitude`: Number - Latitude, for the map.
- `longitude`: Number - Longitude, for the map.
- `formatted_address`: String - The address as the geocoder formats it.
- `geo_status`: String, one of pending | ok | failed, default "pending" - Pending | ok | failed. One of: pending, ok, failed.
- `custom_1`: String - Custom defined field 1.
- `custom_2`: String - Custom defined field 2.
- `custom_3`: String - Custom defined field 3.
- `medias`: Object[] - Pictures of the location.
  - `media`: ObjectId, → Media
  - `_id`: ObjectId
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### PixelData

- `id`: String - Id of the site the event came from.
- `uid`: String - Id of the visitor (cookie).
- `ev`: String - The event (pageload, purchase...).
- `ed.currency`: String
- `ed.value`: Number
- `ed.payment_type`: String
- `ed.coupon`: String
- `ed.items`: Object[]
  - `item_id`: String
  - `item_name`: String
  - `affiliation`: String
  - `coupon`: String
  - `discount`: Number
  - `index`: Number
  - `item_brand`: String
  - `item_category`: String
  - `item_category2`: String
  - `item_category3`: String
  - `item_category4`: String
  - `item_category5`: String
  - `item_list_id`: String
  - `item_list_name`: String
  - `item_variant`: String
  - `location_id`: String
  - `price`: Number
  - `quantity`: Number
  - `_id`: ObjectId
- `ed.shipping_tier`: String
- `ed.virtual_currency_name`: String
- `ed.group_id`: String
- `ed.level_name`: String
- `ed.success`: Boolean
- `ed.level`: Number
- `ed.character`: String
- `ed.method`: String
- `ed.score`: Number
- `ed.transaction_id`: String
- `ed.shipping`: Number
- `ed.tax`: Number
- `ed.search_term`: String
- `ed.content_type`: String
- `ed.content_id`: String
- `ed.creative_name`: String
- `ed.creative_slot`: String
- `ed.promotion_id`: String
- `ed.promotion_name`: String
- `ed.achievement_id`: String
- `v`: String - Version of the tracking script.
- `dl`: String - The page's address.
- `rl`: String - The referring address.
- `ts`: String - When the event happened.
- `de`: String - The page's character encoding.
- `sr`: String - Screen resolution.
- `vp`: String - Viewport size.
- `cd`: String - Screen colour depth.
- `dt`: String - The page's title.
- `bn`: String - Browser name and version.
- `md`: String - Whether the device is mobile.
- `ua`: String - User agent.
- `tz`: String - Visitor's time zone offset in minutes.
- `utm_source`: String - UTM source of the visit.
- `utm_medium`: String - UTM medium.
- `utm_term`: String - UTM term.
- `utm_content`: String - UTM content.
- `utm_campaign`: String - UTM campaign.
- `utm_source_platform`: String - UTM source platform.
- `utm_creative_format`: String - UTM creative format.
- `utm_marketing_tactic`: String - UTM marketing tactic.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Post

- `posted_by`: ObjectId, required, → User - User.id.
- `repost_of`: ObjectId, → Post - Post.id.
- `connected_account_posted_by`: ObjectId, → User - User.id.
- `text`: String - The post's text.
- `title`: String - The post's title.
- `likes`: ObjectId[], → User - User ids.
- `shares`: Object[] - Who shared it, and when.
  - `from`: ObjectId, → User
  - `to`: ObjectId, → User
  - `_id`: ObjectId
- `views`: ObjectId[], → User - User ids.
- `comments`: ObjectId[], → Comment - Comment ids.
- `medias`: Object[] - Pictures and videos of the post.
  - `media`: ObjectId, → Media
  - `vimeo_uri`: String
  - `vimeo_picture`: String
  - `vimeo_url`: String
  - `youtube_url`: String
  - `youtube_picture`: String
  - `gcs_url`: String
  - `gcs_480_30_url`: String
  - `gcs_720_30_url`: String
  - `gcs_1080_30_url`: String
  - `duration`: Number
  - `transcode_status`: String, default "not_started"
  - `_id`: ObjectId
- `thumbnail.media`: ObjectId, → Media
- `keywords`: String[] - Words it is found by.
- `emotion`: String - Positive, neutral, negative.
- `political_spectrum`: String - Far left, left, far right, right, middle.
- `explicit`: String - Yes, no, middle.
- `harmful`: String - Yes, no, maybe.
- `propaganda`: String - Yes, no, middle.
- `advertisement`: String - Yes, no, maybe.
- `engaging`: String - Yes, no, maybe.
- `language`: String - Language of the post.
- `interests`: String[] - From Google Segments.
- `app_category`: String[] - From Google Segments.
- `user_profile`: String[] - Profiles the post is shown to.
- `user_economics`: String - Low, middle, high.
- `user_education`: String - Low, middle, high.
- `marital_status`: String - Single, married.
- `age`: String - 0-18, 18-25, 25-30, 30-35, 35-45, 45-60.
- `sex`: String - Male - female.
- `attractiveness`: String - Low, medium, high,.
- `isAdvertisment`: Boolean, default false - A paid ad.
- `saves`: ObjectId[], → User - User ids.
- `expirable`: Boolean, default false - Disappears after a while.
- `exclusive`: Boolean, default false - Only for subscribers.
- `price_plans`: ObjectId[], → PricePlan - PricePlan ids.
- `targeting.keywords`: String[]
- `targeting.language`: String[]
- `targeting.interests`: String[]
- `targeting.app_category`: String[]
- `targeting.user_economics`: String[]
- `targeting.user_education`: String[]
- `targeting.marital_status`: String[]
- `targeting.age`: String[]
- `targeting.sex`: String[]
- `targeting.isCpc`: Boolean, default false
- `targeting.cost_per_click`: Number, default 0
- `targeting.cost_per_mile`: Number, default 0
- `targeting.daily_budget`: Number, default 0
- `targeting.duration`: Number, default 0
- `targeting.outer_link.text`: String
- `targeting.outer_link.url`: String
- `targeting.locations`: Object[]
  - `type`: String, one of Point
  - `coordinates`: Number[]
  - `_id`: ObjectId
- `targeting.total`: Number, default 0
- `targeting.created_on`: Date
- `targeting.inner_link.text`: String
- `targeting.inner_link.profile_segment`: String
- `targeting.total_clicks`: Number, default 0
- `targeting.unique_clicks`: ObjectId[], → User
- `targeting.campaign_type`: String
- `targeting.related_videos`: ObjectId[], → Post
- `mentions`: ObjectId[], → User - User ids.
- `total_views`: Number, default 0 - How many times it was opened.
- `times_showed`: Number, default 0 - How many times it was shown in a feed.
- `attached_to`: ObjectId, → Post - Post.id.
- `attached_to_cta_text`: String - Text of the post's call-to-action button.
- `poll.question`: String
- `poll.answers`: Object[]
  - `text`: String
  - `users`: ObjectId[], → User
  - `_id`: ObjectId
- `isBlacklist`: Boolean, default false - Contains blacklisted words.
- `isReviewed`: Boolean, default false - A moderator reviewed it.
- `custom_link.heading`: String
- `custom_link.url`: String
- `embeded_link.og:image`: String
- `embeded_link.og:site_name`: String
- `embeded_link.og:title`: String
- `embeded_link.og:url`: String
- `posted_in`: ObjectId, → Group - Group.id.
- `attached_to_service`: ObjectId, → Service - Service.id.
- `attached_to_product`: ObjectId, → Product - Product.id.
- `attached_to_blogpost`: ObjectId, → BlogPost - BlogPost.id.
- `attached_to_program`: ObjectId, → Program - Program.id.
- `attached_to_priceplans`: Boolean, default false - Only subscribers of the attached price plans see it.
- `isWhitelisted`: Boolean, default false - Allowed past moderation.
- `attached_to_group`: ObjectId, → Group - Group.id.
- `reach`: ObjectId[], → User - User ids.
- `showAds`: Boolean, default true - The author allows ads next to it.
- `adminShowAds`: Boolean, default true - The admin allows ads next to it.
- `isAddReviewed`: Boolean, default false - The ad was reviewed.
- `reposts`: ObjectId[], → Post - Post ids.
- `original_post`: ObjectId, → Post - The first reposted post.
- `isHidden`: Boolean, default false - Hidden by a moderator.
- `dislikes`: ObjectId[], → User - User ids.
- `frames`: Object[] - The frames of a story.
  - `media`: ObjectId, → Media
  - `timestamp`: Number
  - `_id`: ObjectId
- `privacy`: String, required, one of everyone | followers | private, default "everyone" - One of: everyone, followers, private.
- `isPinned`: Boolean, default false - Pinned to the top of the author's profile.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### PricePlan

A recurring membership plan.

- `name`: String, required - The plan's name.
- `description`: String - What the plan gives.
- `statement_descriptor`: String, required - Short description of product.
- `plan_features`: Object[] - The plan's features, listed on its card.
  - `feature_type`: String
  - `feature_name`: String
  - `feature_value`: String
  - `_id`: ObjectId
- `price`: Number, required - Price per period.
- `recurring_options.interval`: String, required
- `recurring_options.interval_count`: Number, required
- `link`: String, required - Stripe payment page link.
- `image`: ObjectId, → Media - Media.id.
- `price_id`: String, required - Id of stripe price object.
- `payment_link_id`: String, required - Id of string payment page link.
- `free_trial_days`: Number, default 0 - Days free before the first payment.
- `billing_address_collection`: String, default "auto" - Wheter to collect billing information.
- `owner_id`: ObjectId, → User - User.id.
- `times_showed`: Number, default 0 - How many times it was shown.
- `views`: ObjectId[], → User - User ids.
- `total_views`: Number, default 0 - How many times it was opened.
- `disabled`: Boolean, default false - Cannot be subscribed to.
- `ribbon`: String - Label on the card ("Popular").
- `linked_plans`: ObjectId[], → PricePlan - PricePlan ids.
- `is_hidden`: Boolean, default false - Not listed on the site.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Product

An item the store sells, with its price, images, options and delivery details.

- `name`: String, required - Name of product.
- `url`: String, required - Generated from name, no need to set it manually.
- `static_url`: String - A fixed address kept when the url changes, so old links keep working.
- `ribbon`: String - Short label shown on the product's card, e.g. "New" or "-20%".
- `striked`: String - The old price, shown crossed out next to price: for a sale ("was 12, now 9") set price to 9 and striked to "12". Empty for no sale.
- `price`: Number, required - Price of the product in the site's currency.
- `description`: String - Description of product in html format.
- `product_informations`: Object[] - Extra details listed on the product page, each { name, description } ("Material": "Soy wax").
  - `name`: String, required
  - `description`: String, required
  - `_id`: ObjectId
- `product_options`: Object[] - The choices a buyer makes (Size, Colour): each { name, options: [{ option }] }. An option's text may carry a price change in brackets, "Large (+5)", added to price. Changing the options rebuilds the product's stock lines.
  - `name`: String, required
  - `options`: Object[]
    - `option`: String, required
    - `match_to_collection`: ObjectId, → Collection
    - `quantity`: Number
    - `badge`: String
    - `option_specific_media`: ObjectId, → Media
    - `_id`: ObjectId
  - `informations`: Object[]
    - `name`: String
    - `description`: String
    - `_id`: ObjectId
  - `_id`: ObjectId
- `published`: Boolean, default true - Shown on the site. False hides it from the store and lists without deleting it.
- `available_for_purchase`: Boolean, default true - The whole product can be bought; false stops every option of it. One option sold out ("the white mug ran out") is that option's stock line: quantity 0, tracked.
- `medias`: Object[] - Array of {media}.
  - `media`: ObjectId, → Media
  - `gcs_url`: String
  - `gcs_480_30_url`: String
  - `gcs_720_30_url`: String
  - `gcs_1080_30_url`: String
  - `duration`: Number
  - `vimeo_uri`: String
  - `vimeo_picture`: String
  - `vimeo_url`: String
  - `youtube_url`: String
  - `youtube_picture`: String
  - `thumbnail`: String
  - `_id`: ObjectId
- `collection_id`: ObjectId, → Collection - Collection.id.
- `grouping`: Object[] - The grouping/ filters it appears under inside its category: each { collection_id }.
  - `collection_id`: ObjectId, → Collection
  - `_id`: ObjectId
- `owner_id`: ObjectId, required, → User - User.id.
- `connected_account_owner_id`: ObjectId, → User - User.id.
- `qty`: Number, default 1 - Not the stock: nothing reads it as stock. Stock is kept per option in stock lines (Inventory): read GET /inventory/:product_id/:option, set it with PATCH /inventory/:id {quantity}.
- `origin_address`: String - Name of the address, taken from OriginAdress model, used for filtering.
- `selected`: Boolean, default false - Featured: the home page's highlighted products block shows these first.
- `custom_1`: String - Custom defined field 1.
- `custom_2`: String - Custom defined field 2.
- `custom_3`: String - Custom defined field 3.
- `about_page`: ObjectId, → AboutPage - Reference to AboutPage model, shown in product page.
- `is_digital`: Boolean, default false - Delivered as a download, not shipped.
- `digital_contents`: Object[] - The files a buyer gets.
  - `content`: ObjectId, → DigitalContent
  - `option`: String
  - `_id`: ObjectId
- `suitability_price_plans`: ObjectId[], → PricePlan - PricePlan ids: a signed-in user with one of them sees the product as suitable (isSuitable).
- `isSuitable`: Boolean - Set per request, not stored: whether the signed-in user's price plans match the product's suitability plans.
- `brand`: String - Name of the product brand.
- `brand_logo`: ObjectId, → Media - Logo of the brand, reference to Media model.
- `weight`: Number, default 0 - Weight of the product in kg, for delivery.
- `height`: Number, default 0 - Height of the product in cm, for delivery.
- `length`: Number, default 0 - Length of the product in cm, for delivery.
- `width`: Number, default 0 - Width of the product in cm, for delivery.
- `delivery_type`: String, default "parcel" - Used for delivery, default is parcel, allowed values are books, bulk, letter, parcel or parcel_letter.
- `reference_id`: String - Id of the record it was made from (an import or a clone).
- `secondary_cta.show`: Boolean, default false
- `secondary_cta.title`: String
- `secondary_cta.webUrl`: String
- `secondary_cta.appUrl`: String
- `wildcard_url`: Mixed - The wildcard route the product answers on, when it has one.
- `sku`: Mixed - Stock keeping unit code, when the product has one.
- `reviewed`: Boolean - A moderator reviewed it (marketplace).
- `approved`: Boolean - Approved to be listed (marketplace).
- `expired`: Boolean, default false - Past expires_on and no longer listed.
- `expires_on`: Date - When the listing expires.
- `expire_reminder_sent`: Boolean, default false - The owner was reminded it expires.
- `likes`: ObjectId[], → User - User ids.
- `views`: ObjectId[], → User - User ids.
- `total_views`: Number, default 0 - How many times it was opened.
- `saves`: ObjectId[], → User - User ids.
- `times_showed`: Number, default 0 - How many times it was shown in a list.
- `requiresLogin`: Boolean, default false - Only signed-in users can see it.
- `requiresSubscription`: Boolean, default false - Only subscribers can see it.
- `price_plan_ids`: String[] - Reference to PricePlan ids.
- `linked_products`: Object[] - List of products that are shown for quick add to cart in the product page.
  - `product`: ObjectId, → Product
  - `option`: String
  - `_id`: ObjectId
- `attached_priceplans.name`: String
- `attached_priceplans.priceplans`: ObjectId[], → PricePlan
- `about_section`: ObjectId, → AboutPage - Reference to AboutPage model, shown below the add to cart button.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### ProfessionalAccount

- `user`: ObjectId, required, → User - Id of user, who has created the account.
- `show.services`: Boolean, default false
- `show.staff_members`: Boolean, default false
- `show.blogposts`: Boolean, default false
- `show.programs`: Boolean, default false
- `show.products`: Boolean, default false
- `show.events`: Boolean, default false
- `show.price_plans`: Boolean, default false
- `show.posts`: Boolean, default false
- `reviewed`: Boolean, default false - A moderator reviewed the request.
- `approved`: Boolean, default false - The account was approved as professional.
- `cover`: ObjectId, → Media - Media.id.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Program

An online course: weeks of days, each day a list of steps.

- `title`: String - Name of the program, required.
- `url`: String, required - Generated from title, no need to set it manually.
- `static_url`: String - A fixed address kept when the url changes.
- `header`: String - Short tagline or subtitle shown in listings, optional.
- `body`: String - Full program description in HTML format, optional.
- `medias`: Object[] - The program's pictures.
  - `media`: ObjectId, → Media
  - `gcs_url`: String
  - `gcs_480_30_url`: String
  - `gcs_720_30_url`: String
  - `gcs_1080_30_url`: String
  - `duration`: Number
  - `vimeo_uri`: String
  - `vimeo_picture`: String
  - `vimeo_url`: String
  - `youtube_url`: String
  - `youtube_picture`: String
  - `thumbnail`: String
  - `_id`: ObjectId
- `video`: ObjectId, → Video - Video.id.
- `about_page`: ObjectId, → AboutPage - AboutPage.id.
- `weeks`: Object[] - A list of week objects, required.
  - `isCompleted`: Mixed
  - `progress`: Mixed
  - `title`: String
  - `days`: Object[]
    - `isCompleted`: Mixed
    - `progress`: Mixed
    - `title`: String
    - `steps`: Object[]
      - `title`: String, required
      - `body`: String, required
      - `video`: ObjectId, → Video
      - `medias`: Object[]
      - `about_page`: ObjectId, → AboutPage
      - `timer`: Number, default 0
      - `_id`: ObjectId
    - `_id`: ObjectId
  - `_id`: ObjectId
- `suitability_price_plans`: ObjectId[], → PricePlan - A list of PricePlan ids, marks program as suitable for users with those plans.
- `isSuitable`: Boolean - Set per request, not stored: whether the signed-in user's price plans match the program's suitability plans.
- `popup.title`: String
- `popup.points`: String[]
- `price`: Number, default 0 - Price in the user's currency, default 0.
- `collection_id`: ObjectId, → Collection - Reference to a Collection with name starting with 'program-category/', required.
- `topics`: Object[] - Topics it covers.
  - `collection_id`: ObjectId, → Collection
  - `_id`: ObjectId
- `owner_id`: ObjectId, required, → User - User.id.
- `connected_account_owner_id`: ObjectId, → User - User.id.
- `ribbon`: String - Short badge text shown on the card (e.g. "New", "Best seller"), optional.
- `striked`: String - Original price shown as strikethrough next to the real price, optional.
- `isConsistent`: Boolean, default false - Every week has the same structure.
- `isAcademic`: Boolean, default true - Free-order course, not weeks and days: progress is not tied to a week and day.
- `wildcard_url`: Mixed - The wildcard route it answers on, when it has one.
- `reviewed`: Boolean - A moderator reviewed it.
- `approved`: Boolean - Approved to be listed.
- `likes`: ObjectId[], → User - User ids.
- `views`: ObjectId[], → User - User ids.
- `total_views`: Number, default 0 - How many times it was opened.
- `saves`: ObjectId[], → User - User ids.
- `requiresLogin`: Boolean, default false - Only signed-in users can see it.
- `requiresSubscription`: Boolean, default false - Only subscribers can see it.
- `price_plan_ids`: String[] - A list of price plan id strings that grant access to this program.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Rating

- `email`: String, required - Email of who rated.
- `text`: String - The review's text.
- `medias`: Object[] - Pictures added to the review.
  - `media`: ObjectId, → Media
  - `_id`: ObjectId
- `stars`: Number, required - Rating from 1 to 5.
- `product`: ObjectId, → Product - Product.id.
- `service`: ObjectId, → Service - Service.id.
- `program`: ObjectId, → Program - Program.id.
- `price_plan`: ObjectId, → PricePlan - PricePlan.id.
- `name`: String - Name of who rated.
- `miniapp`: ObjectId, → MiniApp - MiniApp.id.
- `staff_member`: ObjectId, → User - User.id.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Service

A bookable service: its duration, price, the staff who perform it and when it can be booked.

- `title`: String, required - Title of service.
- `url`: String, required - Generated from title, no need to set it manually.
- `static_url`: String - A fixed address kept when the url changes, so old links keep working.
- `header`: String - Short header of service.
- `description`: String - Body text of service.
- `bookable`: Boolean, default true - True if not set.
- `expirable`: Boolean, default false - The listing expires.
- `confirm_bookings`: Boolean, default false - Bookings wait for the business to confirm them.
- `show_notes`: Boolean, default false - Customers can write a note when booking.
- `minutes_delete_bookings`: Number - Number of minutes before the booking expires before being confirmed and is set 'expirable:true'.
- `medias`: Object[] - Attached media objects with ids.
  - `media`: ObjectId, → Media
  - `gcs_url`: String
  - `gcs_480_30_url`: String
  - `gcs_720_30_url`: String
  - `gcs_1080_30_url`: String
  - `duration`: Number
  - `vimeo_uri`: String
  - `vimeo_picture`: String
  - `vimeo_url`: String
  - `youtube_url`: String
  - `youtube_picture`: String
  - `thumbnail`: String
  - `_id`: ObjectId
- `collection_id`: ObjectId, → Collection - Collection, to which the blog post belongs.
- `price`: Number - The price of the service in the globally set currency.
- `online_payment`: Boolean, default false - Bookings are paid online.
- `book_by_date`: Boolean, default false - Whole days are booked, not time slots.
- `book_date_range`: Boolean, default false - A range of days is booked (a stay).
- `start_date`: Date - Date.
- `end_date`: Date - Date.
- `day_offset`: Number, default 0 - How many days ahead of today booking opens; 0 allows today.
- `is_recurring`: Boolean, default false - The service repeats on a schedule.
- `max_participants`: Number, required - How many people can book one slot.
- `session_duration`: Number, required - Length of a slot in minutes.
- `time_between_sessions`: Number, default 0 - Break added after each slot, in minutes.
- `discount`: Object[] - Discounts by number of sessions booked.
  - `days`: Number
  - `per_total_price`: Number
  - `fixed_price`: Number
  - `per_day`: Number
  - `_id`: ObjectId
- `monday.active`: Boolean, default false
- `monday.hours`: Object[]
  - `start`: String
  - `end`: String
  - `_id`: ObjectId
- `tuesday.active`: Boolean, default false
- `tuesday.hours`: Object[]
  - `start`: String
  - `end`: String
  - `_id`: ObjectId
- `wednesday.active`: Boolean, default false
- `wednesday.hours`: Object[]
  - `start`: String
  - `end`: String
  - `_id`: ObjectId
- `thursday.active`: Boolean, default false
- `thursday.hours`: Object[]
  - `start`: String
  - `end`: String
  - `_id`: ObjectId
- `friday.active`: Boolean, default false
- `friday.hours`: Object[]
  - `start`: String
  - `end`: String
  - `_id`: ObjectId
- `saturday.active`: Boolean, default false
- `saturday.hours`: Object[]
  - `start`: String
  - `end`: String
  - `_id`: ObjectId
- `sunday.active`: Boolean, default false
- `sunday.hours`: Object[]
  - `start`: String
  - `end`: String
  - `_id`: ObjectId
- `address`: String - Where is the service performed.
- `staff_member`: ObjectId[], → User - [User.id].
- `owner_id`: ObjectId, → User - User.id.
- `connected_account_owner_id`: ObjectId, → User - User.id.
- `timezone`: Number, default false - Time zone offset the slots are in, in hours.
- `choose_timezone`: Boolean - Customers pick the time zone slots are shown in.
- `origin_address`: String - OriginAddress.id where the service is given.
- `selected`: Boolean, default false - False if not set.
- `custom_1`: String - Custom defined field 1.
- `custom_2`: String - Custom defined field 2.
- `custom_3`: String - Custom defined field 3.
- `about_page`: ObjectId, → AboutPage - AboutPage.id.
- `show_only_about_page`: Boolean, default false - The service page shows only its attached page.
- `suitability_price_plans`: ObjectId[], → PricePlan - PricePlan ids.
- `isSuitable`: Boolean - Set per request, not stored: whether the signed-in user's price plans match the service's suitability plans.
- `booking_only`: Boolean - If the booking page should not show a header and footer.
- `dates_disabled`: String[] - Closed days: dates on which the service cannot be booked (a holiday, a day off). Add a date here to close it.
- `dates_booked`: String[] - Days that are fully booked.
- `receipt_about_page`: ObjectId, → AboutPage - AboutPage.id.
- `wildcard_url`: Mixed - The wildcard route it answers on, when it has one.
- `locked_hours`: Date[] - Hours that cannot be booked.
- `reviewed`: Boolean - A moderator reviewed it (marketplace).
- `approved`: Boolean - Approved to be listed (marketplace).
- `likes`: ObjectId[], → User - User ids.
- `views`: ObjectId[], → User - User ids.
- `total_views`: Number, default 0 - How many times it was opened.
- `saves`: ObjectId[], → User - User ids.
- `times_showed`: Number, default 0 - How many times it was shown in a list.
- `analytics_locales.google_event_custom_title`: String, default "schedule"
- `analytics_locales.facebook_event_custom_title`: String, default "Schedule"
- `analytics_locales.tiktok_event_custom_title`: String
- `analytics_locales.linkedin_event_custom_title`: String
- `analytics_locales.chatgpt_event_custom_title`: String
- `email_text`: String - The text the client will receive inside the email.
- `calendar_description`: String - The text the client will see when adding the appointment inside their calendar.
- `requiresLogin`: Boolean, default false - Only signed-in users can see it.
- `requiresSubscription`: Boolean, default false - Only subscribers of price_plan_ids can see it.
- `price_plan_ids`: String[] - Price plans whose subscribers can see it, with requiresSubscription.
- `calendar_filter`: Object[] - Filters shown on the booking calendar.
  - `collection_id`: ObjectId, → Collection
  - `_id`: ObjectId
- `locked_ranges`: Object[] - Date and time ranges that cannot be booked.
  - `start`: Date
  - `end`: Date
  - `_id`: ObjectId
- `connected_services`: ObjectId[], → Service - Service ids.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### SocialModeSettings

The switches for the site's social app features: feed, posts, groups, chat, marketplace.

- `social_mode`: Boolean, default false - The site runs as a social network (feed, profiles).
- `allow_products`: Boolean, default false - Users can sell products.
- `allow_services`: Boolean, default false - Users can offer services.
- `allow_services_stp`: Boolean, default false - Users can take service payments themselves.
- `allow_blogposts`: Boolean, default false - Users can write blog posts.
- `allow_programs`: Boolean, default false - Users can sell programs.
- `allow_programs_stp`: Boolean, default false - Users can take program payments themselves.
- `allow_posts`: Boolean, default false - Users can post to the feed.
- `allow_ai`: Boolean, default false - AI features are on for users.
- `allow_bites`: Boolean, default false - Short videos are on.
- `allow_long_videos`: Boolean, default false - Long videos are on.
- `allow_explore`: Boolean, default false - The explore page is on.
- `allow_online_payments`: Boolean, default false - Users can take online payments.
- `allow_price_plans`: Boolean, default false - Users can sell subscriptions.
- `allow_boosting_posts`: Boolean, default false - Users can pay to boost posts.
- `allow_single_ai`: Boolean, default false - Users get the single-chat AI.
- `merchant_agreement`: ObjectId, → AboutPage - AboutPage.id.
- `verification_popup`: ObjectId, → AboutPage - AboutPage.id.
- `commission`: Number - Platform commission on users' sales, in percent.
- `home_page`: String, default "home" - What opens first (feed, store, about page...).
- `navigation_pages.bites`: Boolean, default true
- `navigation_pages.long_videos`: Boolean, default true
- `navigation_pages.vouchers`: Boolean, default true
- `navigation_pages.store`: Boolean, default true
- `navigation_pages.programs`: Boolean, default true
- `navigation_pages.services`: Boolean, default true
- `navigation_pages.blogposts`: Boolean, default true
- `navigation_pages.subscription`: Boolean, default true
- `navigation_pages.playlists`: Boolean, default true
- `navigation_pages.partners`: Boolean, default true
- `navigation_pages.contacts`: Boolean, default true
- `navigation_pages.tracker`: Boolean, default true
- `navigation_pages.more`: Boolean, default true
- `navigation_pages.claims`: Boolean, default true
- `navigation_pages.miniapps`: Boolean, default false
- `navigation_pages.events`: Boolean, default false
- `navigation_pages.professional_pages`: Boolean, default false
- `allow_google_login`: Boolean, default true - Sign in with Google is on.
- `use_cdn_for_medias`: Boolean, default false - Pictures and videos load from cdn_for_medias.
- `cdn_for_medias`: String - CDN address for media.
- `use_cdn_for_microservices`: Boolean, default false - Microservices are called through cdn_for_microservices.
- `cdn_for_microservices`: String - CDN address for microservices.
- `cdn_for_sockets`: String - Address of the socket server.
- `paywall.store.has_paywall`: Boolean, default false
- `paywall.store.priceplans`: ObjectId[], → PricePlan
- `paywall.programs.has_paywall`: Boolean, default false
- `paywall.programs.priceplans`: ObjectId[], → PricePlan
- `paywall.services.has_paywall`: Boolean, default false
- `paywall.services.priceplans`: ObjectId[], → PricePlan
- `paywall.blogposts.has_paywall`: Boolean, default false
- `paywall.blogposts.priceplans`: ObjectId[], → PricePlan
- `paywall.subscription.has_paywall`: Boolean, default false
- `paywall.subscription.priceplans`: ObjectId[], → PricePlan
- `paywall.post.has_paywall`: Boolean, default false
- `paywall.post.priceplans`: ObjectId[], → PricePlan
- `paywall.groups.has_paywall`: Boolean, default false
- `paywall.groups.priceplans`: ObjectId[], → PricePlan
- `paywall.professional_pages.has_paywall`: Boolean, default false
- `paywall.professional_pages.priceplans`: ObjectId[], → PricePlan
- `allow_chat`: Boolean, default true - Users can message each other.
- `allow_in_app_notifications`: Boolean, default true - In-app notifications are on.
- `dashboard_pages.following`: Boolean, default true
- `dashboard_pages.recent`: Boolean, default true
- `dashboard_pages.threads`: Boolean, default true
- `dashboard_pages.long_videos`: Boolean, default true
- `dashboard_pages.groups`: Boolean, default true
- `dashboard_pages.about_pages`: Boolean, default true
- `dashboard_pages.mini_apps`: Boolean, default true
- `dashboard_pages.blogposts`: Boolean, default true
- `dashboard_pages.products`: Boolean, default true
- `dashboard_pages.services`: Boolean, default true
- `dashboard_pages.price_plans`: Boolean, default true
- `dashboard_pages.programs`: Boolean, default true
- `dashboard_pages.claims`: Boolean, default true
- `dashboard_pages.bites`: Boolean, default true
- `dashboard_pages.playlists`: Boolean, default true
- `dashboard_pages.partners`: Boolean, default true
- `dashboard_pages.contacts`: Boolean, default true
- `dashboard_pages.tracker`: Boolean, default true
- `dashboard_pages.vouchers`: Boolean, default true
- `dashboard_pages.explore`: Boolean, default true
- `feed_menus`: String, default "grid" - Grid, row.
- `allow_miniapps`: Boolean, default false - Mini apps are on.
- `about_pages.groups`: ObjectId, → AboutPage
- `user_groups`: Boolean, default true - Users can create groups.
- `allow_professional_pages`: Boolean, default false - Professional accounts get their own pages.
- `allow_professional_account_registration`: Boolean, default false - Users can apply for a professional account.
- `locations_map.enabled`: Boolean, default false
- `use_companion_bookings`: Boolean, default false - Bookings are handled by the companion app.
- `confirm_bookings_call`: Boolean, default false - The AI phone agent calls to confirm bookings.
- `require_professional_account.services`: Boolean, default false
- `require_professional_account.products`: Boolean, default false
- `require_professional_account.programs`: Boolean, default false
- `require_professional_account.blogposts`: Boolean, default false
- `require_professional_account.subscriptions`: Boolean, default false
- `hide_feed_menus`: Boolean, default false - Feed menus are hidden.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Subscription

- `stripe_subscription_id`: String - Id of stripe substring object.
- `user_id`: ObjectId, required, → User - Id of user who subscribet to price plan.
- `status`: Number, default 0 - 1 active, 0 cancelled or unpaid.
- `payment_intent_id`: String - Id of stripe payment intend object.
- `price_plan`: ObjectId, required, → PricePlan - Id of the subscribed price plan.
- `rating_mail_sent`: Boolean, default false - The email asking for a rating was sent.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### User

A person with an account on the site - customer, staff member or admin.

- `name`: String - Display name.
- `email`: String, required - Email, used to sign in.
- `avatar`: ObjectId - Media.id of the profile picture.
- `social_avatar`: String - Profile picture from a social sign-in.
- `isAdmin`: Boolean, default false - Can use the admin.
- `isStaff`: Boolean, default false - A staff member who can be booked.
- `owner_id`: ObjectId - User.id of the admin who added this user.
- `organization_name`: String - Company name.
- `firstname`: String - First name.
- `lastname`: String - Last name.
- `phone_number`: String - Phone number.
- `address`: String - Address.
- `city`: String - City.
- `state`: String - State or region.
- `country`: String - Country.
- `zip_code`: String - Postal code.
- `tax_identification_number`: String - Tax number.
- `notes`: String - Notes kept on the user.
- `isConfirmed`: Boolean, default false - The email was confirmed.
- `number_of_sales`: Number, default 0 - How many sales the user made (marketplace).
- `stripe_id`: String - The user's id in Stripe.
- `paypal_id`: String - The user's PayPal id.
- `access_level`: Number - Admin permission level; 0 is full access.
- `can_edit.site`: Boolean, default true
- `can_edit.crm`: Boolean, default true
- `can_edit.store`: Boolean, default true
- `can_edit.payments`: Boolean, default true
- `can_edit.staff`: Boolean, default true
- `validation_code`: String - Code sent to confirm the email.
- `price_plans`: ObjectId[], → PricePlan - PricePlan ids.
- `emotion`: String - Positive, neutral, negative.
- `political_spectrum`: String - Far left, left, far right, right, middle.
- `language`: Mixed - Multiple objects inside - key: value - example - "EN": 5 (5 being the weight);.
- `interests`: Mixed - Multiple objects inside - key: value - example - "hobby": 5 (5 being the weight);.
- `app_category`: Mixed - Multiple objects inside - key: value - example - "hobby": 5 (5 being the weight);.
- `user_profile`: Mixed - Multiple objects inside - key: value - example - "intelligent": 5 (5 being the weight);.
- `user_economics`: String - Low, middle, high.
- `user_education`: String - Low, middle, high.
- `marital_status`: String - Single, married.
- `age`: String - 0-18, 18-25, 25-30, 30-35, 35-45, 45-60.
- `sex`: String - Male - female.
- `attractiveness`: String - Low, medium, high.
- `following`: ObjectId[], → User - User ids.
- `followers`: ObjectId[], → User - User ids.
- `handle`: String - Unique @handle.
- `saved_posts`: ObjectId[], → Post - Post ids.
- `blocked_users`: ObjectId[], → User - User ids.
- `blocked_by`: ObjectId[], → User - User ids.
- `bio`: String - About the user.
- `wallet`: Number, default 0 - Balance in the user's wallet.
- `ip_location.city`: String
- `ip_location.continent_name`: String
- `ip_location.country_name`: String
- `ip_location.country_subdivision`: String
- `ip_location.location_latitude`: Number
- `ip_location.location_longitude`: Number
- `ip_location.last_updated`: Date
- `ip_location.ip_address`: String
- `ip_location.zip_code`: String
- `ip_location.dialing_code`: String
- `location`: Embedded - The user's chosen location.
  - `type`: String, one of Point
  - `coordinates`: Number[]
  - `_id`: ObjectId
- `checkout_recovery_at`: Date - When we last emailed them about a Premium checkout they left (utils/checkout-recovery).
- `search_history`: String[] - What the user searched for.
- `isRestricted`: Boolean, default false - Restricted by a moderator.
- `isMonetized`: Boolean, default false - Earns from their content.
- `monetization_request.isRequested`: Boolean, default false
- `monetization_request.requested_on`: Date
- `sentFollowersEmail`: Date - When the followers summary email was last sent.
- `isShadowbanned`: Boolean, default false - Their content is hidden from others without telling them.
- `custom_url`: Object[] - Custom addresses for their profile.
  - `heading`: String
  - `url`: String
  - `_id`: ObjectId
- `isWhitelisted`: Boolean, default false - Skips moderation.
- `isReviewedWhitelist`: Boolean, default false - The whitelist request was reviewed.
- `advertiser_id`: String - Id as an advertiser.
- `selected_events`: String[] - Events the user follows.
- `profile_feed_style`: String, default "list" - How their profile feed looks (grid, list).
- `hidden_users`: ObjectId[], → User - User ids whose posts are hidden from this user's feed.
- `isVerified`: Boolean, default false - Shows the verified badge.
- `saved_products`: ObjectId[], → Product - Product ids the user saved.
- `saved_programs`: ObjectId[], → Program - Program ids the user saved.
- `saved_blogposts`: ObjectId[], → Blogpots - BlogPost ids the user saved.
- `saved_services`: ObjectId[], → Service - Service ids the user saved.
- `last_used_miniapps`: ObjectId[], → MiniApp - MiniApp ids.
- `has_disabled_seen`: Boolean, default false - Read receipts are off.
- `other_address`: Object[] - Other saved addresses.
  - `firstname`: String
  - `lastname`: String
  - `email`: String
  - `phone_number`: String
  - `address`: String
  - `city`: String
  - `state`: String
  - `country`: String
  - `zip_code`: String
  - `_id`: ObjectId
- `is_disabled`: Boolean, default false - The account is disabled.
- `delete_date`: Date - When the account will be deleted.
- `trial_price_plans`: Object[] - Price plans the user is trying, and until when.
  - `end_date`: Date
  - `start_date`: Date
  - `price_plan`: ObjectId, → PricePlan
  - `_id`: ObjectId
- `lastActivity`: Date - When the user was last active.
- `attached_dynamic_models`: Object[] - Records of custom models attached to the user.
  - `model`: ObjectId, → DynamicModel
  - `document`: ObjectId
  - `_id`: ObjectId
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### UserEngagementNotification

- `type`: String - Liked_post, commented, liked_comment, replied_to, mentioned, sent_message, search, followed, profile_visit, system, group_request_received, group_request_accepted, activity_boost.
- `title`: String, required - The notification's heading.
- `body`: String - The notification's text.
- `owner_id`: ObjectId, → User - User.id.
- `from`: ObjectId, → User - User.id.
- `post`: ObjectId, → Post - Post.id.
- `group`: ObjectId, → Group - Group.id.
- `sendToAll`: Boolean, default false - Goes to every user.
- `comment`: ObjectId, → Comment - Comment.id.
- `is_received`: Boolean, default false - Delivered to the user.
- `is_seen`: Boolean, default false - The user saw it.
- `url`: String - Where tapping it leads.
- `image`: String - Picture shown with it.
- `service`: ObjectId, → Service - Service.id.
- `product`: ObjectId, → Product - Product.id.
- `blogpost`: ObjectId, → BlogPost - BlogPost.id.
- `program`: ObjectId, → Program - Program.id.
- `booking`: ObjectId, → Booking - Booking.id.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### Video

A video on the site - uploaded or generated - shown in galleries and programs.

- `name`: String, required - The video's title.
- `link`: String - Link to the video.
- `collection_id`: ObjectId, → Collection - Collection.id.
- `media_id`: ObjectId, → Media - Media.id.
- `selected`: Boolean, default false - Featured: the home page's highlighted videos block shows these first.
- `custom_1`: String - Custom defined field 1.
- `custom_2`: String - Custom defined field 2.
- `custom_3`: String - Custom defined field 3.
- `suitability_price_plans`: ObjectId[], → PricePlan - PricePlan ids.
- `isSuitable`: Boolean - Set per request, not stored: whether the signed-in user's price plans match the video's suitability plans.
- `views`: ObjectId[], → User - User ids.
- `total_views`: Number, default 0 - How many times it was opened.
- `times_showed`: Number, default 0 - How many times it was shown in a list.
- `owner_id`: ObjectId, → User - User.id.
- `requiresLogin`: Boolean, default false - Only signed-in users can watch it.
- `requiresSubscription`: Boolean, default false - Only subscribers of price_plan_ids can watch it.
- `price_plan_ids`: String[] - Price plans whose subscribers can watch it.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date

### VideoInteraction

- `start`: Number, required - Second the viewer started watching from.
- `end`: Number, required - Second they stopped at.
- `watch_time`: Number, required - Seconds watched.
- `video_viewer`: ObjectId, required, → User - User.id.
- `video_id`: ObjectId, required, → Post - Post.id.
- `video_owner`: ObjectId, required, → User - User.id.
- `_id`: ObjectId
- `updatedAt`: Date
- `createdAt`: Date
