swagger: "2.0"
info:
description: |
This is the REST API for [trashnothing.com](https://trashnothing.com).
To learn more about the API or to register your app for use with the API
visit the [trash nothing Developer page](https://trashnothing.com/developer).
NOTE: All date-time values are [UTC](https://en.wikipedia.org/wiki/Coordinated_Universal_Time)
and are in [ISO 8601 format](https://en.wikipedia.org/wiki/ISO_8601) (eg. 2019-02-03T01:23:53).
version: "1.3"
title: trash nothing
termsOfService: >
https://trashnothing.com/terms
host: trashnothing.com
basePath: /api/v1.3
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
tags:
- name: users
description: Retrieve and update user data.
- name: posts
description: Retrieve and update posts.
- name: groups
description: Search, subscribe and unsubscribe to groups.
- name: photos
description: Upload, delete and rotate photos.
- name: messages
description: >
Manage conversations and messages with other users.
It's important to note that messages are always sent by email to the users.
So it's possible to create a fully functional app using the trash nothing API
without using any of the conversations or messages API endpoints. These API
endpoints are useful for developers who want to build a complete messaging interface
into their app.
- name: stories
description: Retrieve and submit stories.
- name: misc
description: Miscellaneous functionality.
schemes:
- https
#
#
paths:
/users/me:
get:
tags:
- users
summary: Retrieve current user
operationId: get_current_user
produces:
- application/json
responses:
200:
description: User data
schema:
$ref: "#/definitions/CurrentUser"
404:
description: User not found.
put:
tags:
- users
summary: Update current user
operationId: update_current_user
description: >
Update the current user. All fields are optional so requests can update just one or multiple user properties at a time.
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: firstname
in: formData
description: The first name of the user.
required: false
type: string
maxLength: 64
- name: lastname
in: formData
description: The last name of the user.
required: false
type: string
maxLength: 64
- name: public_name
in: formData
description: >
Whether or not the users' first and last name will be visible to other users.
Set to 1 to enable and 0 to disable.
required: false
type: integer
- name: email_posts_frequency
in: formData
description: >
How often new post email notifications are sent to the user.
One of: weekly, twice_weekly, daily, 12_hours, 8_hours, 6_hours, 4_hours, 2_hours, hourly
To turn off new post email notifications, set this to an empty string.
required: false
type: string
- name: digest_photos
in: formData
description: >
Whether or not to include photos in the digest emails.
Set to 1 to enable photos and 0 to disable photos.
required: false
type: integer
- name: email_post_reminders
in: formData
description: If set to 1, the user will receive emails to remind them to handle their old posts. To disable, set to 0.
required: false
type: integer
- name: password
in: formData
description: >
A new password for the users' account. When setting a new password, the old_password parameter must be passed and set
to the users' current password.
NOTE: The password and old_password properties can NOT be used when the user property
has_password is false. Instead, use the password reset endpoint to have a new password emailed to the user.
required: false
type: string
- name: old_password
in: formData
description: The users current password. This is required when the user is changing their password.
required: false
type: string
- name: profile_image_source
in: formData
description: >
The source of the users' profile image. The values this can be set to change dynamically based on the users' account.
To get the values that can be used, use the source properties returned by the profile images endpoint.
required: false
type: string
- name: last_listings_view
in: formData
description: The UTC date and time when the user last viewed the newest posts on the All Posts page.
required: false
type: string
format: date-time
- name: public_post_sources
in: formData
description: >
A comma separated list of the sources to show public posts from. Currently only 'trashnothing' is supported.
If not passed, all sources will be enabled.
If set to an empty string, no sources will be enabled which effectively disables public posts for the user
so that the user will only see posts from the groups they are a member of. Setting to an empty string is only
allowed if the user is a member of one or more groups.
required: false
type: string
- name: show_all_group_posts
in: formData
description: >
Set to 1 to show all group posts on the main posts page and in the digests. Set to 0 to only show group posts
in the area defined by the users' location. Can only be set to 0 if the users' location is already set.
required: false
type: integer
- name: special_notices
in: formData
description: >
Whether or not the user wants to receive special notice emails from the groups they are a member of.
Special notices are admin posts that the group moderators choose to send out by email.
Set to 1 to enable and 0 to disable.
required: false
type: integer
- name: about_me
in: formData
description: A short bio a user has written about themselves to help other members get to know them better.
required: false
type: string
maxLength: 4096
- name: email_search_alerts
in: formData
description: If set to 1, the user will receive emails when new posts that match one of their search alerts. To disable, set to 0.
required: false
type: integer
- name: notify_about_reposts
in: formData
description: >
If set to 1, the user will be notified about reposts.
This affects digests and search alerts.
If set to 0, the user will not be notified about reposts.
This does not affect the posts that are returned by the /posts endpoint
which has an include_reposts option for this purpose.
See the repost_count field of post objects for details about how reposts are identified.
required: false
type: integer
- name: email_message_delay
in: formData
description: >
How quickly new messages from other users are emailed to this user.
One of: immediate, 30_minutes, 1_hour, 2_hours, 4_hours, 6_hours, 8_hours
If set to anything other than immediate, the user will receive a digest email
summarizing all of the new messages that they haven't viewed.
required: false
type: string
- name: email_newsletters
in: formData
description: If set to 1, the user will receive occasional email newsletters from trash nothing. To disable, set to 0.
required: false
type: string
responses:
200:
description: The updated user data.
schema:
$ref: "#/definitions/CurrentUser"
400:
description: Invalid parameter.
/users/{user_id}:
get:
tags:
- users
summary: Retrieve a user
operationId: get_user
produces:
- application/json
parameters:
- name: user_id
in: path
description: A user ID.
required: true
type: string
responses:
200:
description: User data
schema:
$ref: "#/definitions/User"
404:
description: User not found.
/users/{user_id}/display:
get:
tags:
- users
summary: Retrieve user display info
description: >
Retrieve a user and information related to the user (eg. recent posts) that is useful for displaying
a more detailed view of the user.
operationId: get_user_and_related_data
produces:
- application/json
parameters:
- name: user_id
in: path
description: A user ID.
required: true
type: string
responses:
200:
description: The user and related data.
schema:
type: object
properties:
user:
$ref: "#/definitions/User"
posts:
type: array
description: >
Other active posts from the user in the last 90 days.
A maximum of 30 posts will be returned.
items:
$ref: "#/definitions/Post"
offer_count:
type: integer
description: Count of offer posts made by the user in the last 90 days.
wanted_count:
type: integer
description: Count of wanted posts made by the user in the last 90 days.
feedback:
type: array
description: Feedback the current user has left on the user.
items:
$ref: "#/definitions/Feedback"
404:
description: User not found.
/users/me/posts:
get:
tags:
- users
summary: List current users' posts
description: >
NOTE: In order to make it easier to see all a users' posts, the current users' location preferences are not applied when listing or searching posts from a single user. If location based filtering of the posts is needed, the latitude, longitude and radius parameters may be used.
operationId: get_current_user_posts
produces:
- application/json
parameters:
- name: sort_by
in: query
description: >
How to sort the posts that are returned. One of: date, active, distance
Date sorting will sort posts from newest to oldest.
Active sorting will sort active posts before satisfied, withdrawn and expired posts and then sort by date.
Distance sorting will sort the closest posts first.
required: false
default: date
type: string
- name: types
in: query
description: >
A comma separated list of the post types to return. The available post types are: offer, taken, wanted, received, admin
required: true
type: string
- name: sources
in: query
description: >
A comma separated list of the post sources to retrieve posts from. The available sources are:
groups, trashnothing, open_archive_groups.
The trashnothing source is for public posts that are posted on trash nothing but are not associated with any group.
The open_archive_groups source provides a way to easily request posts from groups that have open_archives set to true
without having to pass a group_ids parameter. When passed, it will automatically return posts from open archive groups
that are within the area specified by the latitude, longitude and radius parameters
(or the current users' location if
latitude, longitude and radius aren't passed).
NOTE: For requests using an api key instead of oauth, passing the trashnothing source or the open_archive_groups source
makes the latitude, longitude and radius parameters required.
required: true
type: string
- name: group_ids
in: query
description: >
A comma separated list of the group IDs to retrieve posts from.
This parameter is only used if the 'groups' source is passed in the sources parameter
and only groups that the current user is a member of or that are open archives groups
will be used (the group IDs of other groups will be silently discarded*).
NOTE: For requests using an api key instead of oauth, this field is required if the 'groups' source is passed.
In addition, only posts from groups that have open_archives set to true will be used
(the group IDS of other groups will be silently discarded*).
*To determine which group IDs were used and which were discarded, use the group_ids field in the response.
required: false
default: The group IDs of every group the current user is a member of.
type: string
- name: per_page
in: query
description: The number of posts to return per page (must be >= 1 and <= 100).
required: false
default: 20
minimum: 1
maximum: 100
type: integer
- name: page
in: query
description: The page of posts to return.
required: false
default: 1
minimum: 1
type: integer
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
- name: latitude
in: query
description: >
The latitude of a point around which to return posts.
required: false
type: number
- name: longitude
in: query
description: >
The longitude of a point around which to return posts.
required: false
type: number
- name: radius
in: query
description: >
The radius in meters of a circle centered at the point defined by the latitude and longitude parameters.
When latitude, longitude and radius are passed, only posts within the circle defined by these parameters will be returned.
required: false
type: number
minimum: 0
maximum: 257500
- name: date_min
in: query
description: >
Only posts newer than or equal to this UTC date and time will be returned.
required: false
type: string
format: date-time
- name: date_max
in: query
description: Only posts older than this UTC date and time will be returned.
required: false
type: string
format: date-time
- name: outcomes
in: query
type: string
required: false
default: ''
description: >
A comma separated list of the post outcomes to return. The available post outcomes are: satisfied, withdrawn
There are also a couple special values that can be passed.
If set to an empty string (the default), only posts that are not satisfied and not withdrawn and not expired are returned.
If set to 'all', all posts will be returned no matter what outcome the posts have.
If set to 'not-promised', only posts that are not satisfied ant not withdrawn and not expired and not promised are returned.
#
- name: user_state
in: query
type: string
required: false
default: ''
description: >
If user_state is set, only posts matching the state specified will be returned. Only one state may be passed
and it must be one of the following: viewed, replied, bookmarked
NOTE: This option will only work with oauth requests.
- name: include_reposts
in: query
description: >
If set to 1 (the default), posts that are reposts will be included.
If set to 0, reposts will be excluded.
See the repost_count field of post objects for details about how reposts are identified.
required: false
default: 1
minimum: 0
maximum: 1
type: integer
responses:
200:
description: The posts and paging data.
schema:
type: object
properties:
posts:
type: array
items:
$ref: "#/definitions/Post"
num_posts:
type: integer
description: The total number of posts available.
page:
type: integer
description: The page number of the posts being returned.
per_page:
type: integer
description: The number of posts being returned per page.
num_pages:
type: integer
description: The total number of pages available.
start_index:
type: integer
description: The index of the first post being returned (an integer between 1 and num_posts).
end_index:
type: integer
description: The index of the last post being returned (an integer between start_index and num_posts).
group_ids:
type: array
items:
type: string
description: >
The IDs of the groups that the posts were retrieved from (will be null when no group IDs were used).
These IDs may be a subset of the requested group IDs when a request includes group IDs for groups
that are not open archives and that the current user is not a member of. If the open_archive_groups
source is used, these IDs may include the IDs of open archive groups that weren't present in the
group_ids parameter of the request.
last_listings_view:
type: string
format: date-time
description: >
The UTC date and time when the current user last viewed the newest posts on the All Posts page (may be null).
NOTE: For this to be accurate, clients must update the last_listings_view property of the current user every time the user is shown
the newest posts on the All Posts page.
NOTE: For requests using an api key instead of oauth, this field is always null.
400:
description: Missing or invalid parameters.
/users/{user_id}/posts:
get:
tags:
- users
summary: List posts by a user
description: >
NOTE: In order to make it easier to see all a users' posts, the current users' location preferences are not applied when listing or searching posts from a single user. If location based filtering of the posts is needed, the latitude, longitude and radius parameters may be used.
operationId: get_user_posts
produces:
- application/json
parameters:
- name: user_id
in: path
description: >
The user ID of the user whose posts will be retrieved.
Using 'me' as the user_id will return the posts for the current user.
required: true
type: string
- name: sort_by
in: query
description: >
How to sort the posts that are returned. One of: date, active, distance
Date sorting will sort posts from newest to oldest.
Active sorting will sort active posts before satisfied, withdrawn and expired posts and then sort by date.
Distance sorting will sort the closest posts first.
required: false
default: date
type: string
- name: types
in: query
description: >
A comma separated list of the post types to return. The available post types are: offer, taken, wanted, received, admin
required: true
type: string
- name: sources
in: query
description: >
A comma separated list of the post sources to retrieve posts from. The available sources are:
groups, trashnothing, open_archive_groups.
The trashnothing source is for public posts that are posted on trash nothing but are not associated with any group.
The open_archive_groups source provides a way to easily request posts from groups that have open_archives set to true
without having to pass a group_ids parameter. When passed, it will automatically return posts from open archive groups
that are within the area specified by the latitude, longitude and radius parameters
(or all the open archive groups the requested user has posted to if
latitude, longitude and radius aren't passed).
NOTE: For requests using an api key instead of oauth, passing the trashnothing source or the open_archive_groups source
makes the latitude, longitude and radius parameters required.
required: true
type: string
- name: group_ids
in: query
description: >
A comma separated list of the group IDs to retrieve posts from.
This parameter is only used if the 'groups' source is passed in the sources parameter
and only groups that the current user is a member of or that are open archives groups
will be used (the group IDs of other groups will be silently discarded*).
NOTE: For requests using an api key instead of oauth, this field is required if the 'groups' source is passed.
In addition, only posts from groups that have open_archives set to true will be used
(the group IDS of other groups will be silently discarded*).
*To determine which group IDs were used and which were discarded, use the group_ids field in the response.
required: false
default: The group IDs of every group the current user is a member of.
type: string
- name: per_page
in: query
description: The number of posts to return per page (must be >= 1 and <= 100).
required: false
default: 20
minimum: 1
maximum: 100
type: integer
- name: page
in: query
description: The page of posts to return.
required: false
default: 1
minimum: 1
type: integer
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
- name: latitude
in: query
description: >
The latitude of a point around which to return posts.
required: false
type: number
- name: longitude
in: query
description: >
The longitude of a point around which to return posts.
required: false
type: number
- name: radius
in: query
description: >
The radius in meters of a circle centered at the point defined by the latitude and longitude parameters.
When latitude, longitude and radius are passed, only posts within the circle defined by these parameters will be returned.
required: false
type: number
minimum: 0
maximum: 257500
- name: date_min
in: query
description: >
Only posts newer than or equal to this UTC date and time will be returned.
required: false
type: string
format: date-time
- name: date_max
in: query
description: Only posts older than this UTC date and time will be returned.
required: false
type: string
format: date-time
- name: outcomes
in: query
type: string
required: false
default: ''
description: >
A comma separated list of the post outcomes to return. The available post outcomes are: satisfied, withdrawn
There are also a couple special values that can be passed.
If set to an empty string (the default), only posts that are not satisfied and not withdrawn and not expired are returned.
If set to 'all', all posts will be returned no matter what outcome the posts have.
If set to 'not-promised', only posts that are not satisfied ant not withdrawn and not expired and not promised are returned.
#
- name: include_reposts
in: query
description: >
If set to 1 (the default), posts that are reposts will be included.
If set to 0, reposts will be excluded.
See the repost_count field of post objects for details about how reposts are identified.
required: false
default: 1
minimum: 0
maximum: 1
type: integer
responses:
200:
description: The posts and paging data.
schema:
type: object
properties:
posts:
type: array
items:
$ref: "#/definitions/Post"
num_posts:
type: integer
description: The total number of posts available.
page:
type: integer
description: The page number of the posts being returned.
per_page:
type: integer
description: The number of posts being returned per page.
num_pages:
type: integer
description: The total number of pages available.
start_index:
type: integer
description: The index of the first post being returned (an integer between 1 and num_posts).
end_index:
type: integer
description: The index of the last post being returned (an integer between start_index and num_posts).
group_ids:
type: array
items:
type: string
description: >
The IDs of the groups that the posts were retrieved from (will be null when no group IDs were used).
These IDs may be a subset of the requested group IDs when a request includes group IDs for groups
that are not open archives and that the current user is not a member of. If the open_archive_groups
source is used, these IDs may include the IDs of open archive groups that weren't present in the
group_ids parameter of the request.
last_listings_view:
type: string
format: date-time
description: >
The UTC date and time when the current user last viewed the newest posts on the All Posts page (may be null).
NOTE: For this to be accurate, clients must update the last_listings_view property of the current user every time the user is shown
the newest posts on the All Posts page.
NOTE: For requests using an api key instead of oauth, this field is always null.
400:
description: Missing or invalid parameters.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
/users/me/posts/search:
get:
tags:
- users
summary: Search current users' posts
description: >
Searching posts takes the same arguments as listing posts except for the addition of the search and sort_by parameters.
operationId: search_current_user_posts
produces:
- application/json
parameters:
- name: search
in: query
description: The search query used to find posts.
required: true
type: string
- name: sort_by
in: query
description: >
How to sort the posts that are returned. One of: relevance, date, active, distance
Relevance sorting will sort the posts that best match the search query first.
Date sorting will sort posts from newest to oldest.
Active sorting will sort active posts before satisfied, withdrawn and expired posts and then sort by date.
Distance sorting will sort the closest posts first.
required: false
default: relevance
type: string
- name: types
in: query
description: >
A comma separated list of the post types to return. The available post types are: offer, taken, wanted, received, admin
required: true
type: string
- name: sources
in: query
description: >
A comma separated list of the post sources to retrieve posts from. The available sources are:
groups, trashnothing, open_archive_groups.
The trashnothing source is for public posts that are posted on trash nothing but are not associated with any group.
The open_archive_groups source provides a way to easily request posts from groups that have open_archives set to true
without having to pass a group_ids parameter. When passed, it will automatically return posts from open archive groups
that are within the area specified by the latitude, longitude and radius parameters
(or the current users' location if
latitude, longitude and radius aren't passed).
NOTE: For requests using an api key instead of oauth, passing the trashnothing source or the open_archive_groups source
makes the latitude, longitude and radius parameters required.
required: true
type: string
- name: group_ids
in: query
description: >
A comma separated list of the group IDs to retrieve posts from.
This parameter is only used if the 'groups' source is passed in the sources parameter
and only groups that the current user is a member of or that are open archives groups
will be used (the group IDs of other groups will be silently discarded*).
NOTE: For requests using an api key instead of oauth, this field is required if the 'groups' source is passed.
In addition, only posts from groups that have open_archives set to true will be used
(the group IDS of other groups will be silently discarded*).
*To determine which group IDs were used and which were discarded, use the group_ids field in the response.
required: false
default: The group IDs of every group the current user is a member of.
type: string
- name: per_page
in: query
description: The number of posts to return per page (must be >= 1 and <= 100).
required: false
default: 20
minimum: 1
maximum: 100
type: integer
- name: page
in: query
description: The page of posts to return.
required: false
default: 1
minimum: 1
type: integer
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
- name: latitude
in: query
description: >
The latitude of a point around which to return posts.
required: false
type: number
- name: longitude
in: query
description: >
The longitude of a point around which to return posts.
required: false
type: number
- name: radius
in: query
description: >
The radius in meters of a circle centered at the point defined by the latitude and longitude parameters.
When latitude, longitude and radius are passed, only posts within the circle defined by these parameters will be returned.
required: false
type: number
minimum: 0
maximum: 257500
- name: date_min
in: query
description: >
Only posts newer than or equal to this UTC date and time will be returned.
required: false
type: string
format: date-time
- name: date_max
in: query
description: Only posts older than this UTC date and time will be returned.
required: false
type: string
format: date-time
- name: outcomes
in: query
type: string
required: false
default: ''
description: >
A comma separated list of the post outcomes to return. The available post outcomes are: satisfied, withdrawn
There are also a couple special values that can be passed.
If set to an empty string (the default), only posts that are not satisfied and not withdrawn and not expired are returned.
If set to 'all', all posts will be returned no matter what outcome the posts have.
If set to 'not-promised', only posts that are not satisfied ant not withdrawn and not expired and not promised are returned.
#
- name: user_state
in: query
type: string
required: false
default: ''
description: >
If user_state is set, only posts matching the state specified will be returned. Only one state may be passed
and it must be one of the following: viewed, replied, bookmarked
NOTE: This option will only work with oauth requests.
- name: include_reposts
in: query
description: >
If set to 1 (the default), posts that are reposts will be included.
If set to 0, reposts will be excluded.
See the repost_count field of post objects for details about how reposts are identified.
required: false
default: 1
minimum: 0
maximum: 1
type: integer
responses:
200:
description: The posts and paging data.
schema:
type: object
properties:
posts:
type: array
items:
$ref: "#/definitions/PostSearchResult"
num_posts:
type: integer
description: The total number of posts available.
page:
type: integer
description: The page number of the posts being returned.
per_page:
type: integer
description: The number of posts being returned per page.
num_pages:
type: integer
description: The total number of pages available.
start_index:
type: integer
description: The index of the first post being returned (an integer between 1 and num_posts).
end_index:
type: integer
description: The index of the last post being returned (an integer between start_index and num_posts).
group_ids:
type: array
items:
type: string
description: >
The IDs of the groups that the posts were retrieved from (will be null when no group IDs were used).
These IDs may be a subset of the requested group IDs when a request includes group IDs for groups
that are not open archives and that the current user is not a member of. If the open_archive_groups
source is used, these IDs may include the IDs of open archive groups that weren't present in the
group_ids parameter of the request.
400:
description: Missing or invalid parameters.
/users/{user_id}/posts/search:
get:
tags:
- users
summary: Search posts by a user
description: >
Searching posts takes the same arguments as listing posts except for the addition of the search and sort_by parameters.
operationId: search_user_posts
produces:
- application/json
parameters:
- name: user_id
in: path
description: >
The user ID of the user whose posts will be retrieved.
Using 'me' as the user_id will return the posts for the current user.
required: true
type: string
- name: search
in: query
description: The search query used to find posts.
required: true
type: string
- name: sort_by
in: query
description: >
How to sort the posts that are returned. One of: relevance, date, active, distance
Relevance sorting will sort the posts that best match the search query first.
Date sorting will sort posts from newest to oldest.
Active sorting will sort active posts before satisfied, withdrawn and expired posts and then sort by date.
Distance sorting will sort the closest posts first.
required: false
default: relevance
type: string
- name: types
in: query
description: >
A comma separated list of the post types to return. The available post types are: offer, taken, wanted, received, admin
required: true
type: string
- name: sources
in: query
description: >
A comma separated list of the post sources to retrieve posts from. The available sources are:
groups, trashnothing, open_archive_groups.
The trashnothing source is for public posts that are posted on trash nothing but are not associated with any group.
The open_archive_groups source provides a way to easily request posts from groups that have open_archives set to true
without having to pass a group_ids parameter. When passed, it will automatically return posts from open archive groups
that are within the area specified by the latitude, longitude and radius parameters
(or all the open archive groups the requested user has posted to if
latitude, longitude and radius aren't passed).
NOTE: For requests using an api key instead of oauth, passing the trashnothing source or the open_archive_groups source
makes the latitude, longitude and radius parameters required.
required: true
type: string
- name: group_ids
in: query
description: >
A comma separated list of the group IDs to retrieve posts from.
This parameter is only used if the 'groups' source is passed in the sources parameter
and only groups that the current user is a member of or that are open archives groups
will be used (the group IDs of other groups will be silently discarded*).
NOTE: For requests using an api key instead of oauth, this field is required if the 'groups' source is passed.
In addition, only posts from groups that have open_archives set to true will be used
(the group IDS of other groups will be silently discarded*).
*To determine which group IDs were used and which were discarded, use the group_ids field in the response.
required: false
default: The group IDs of every group the current user is a member of.
type: string
- name: per_page
in: query
description: The number of posts to return per page (must be >= 1 and <= 100).
required: false
default: 20
minimum: 1
maximum: 100
type: integer
- name: page
in: query
description: The page of posts to return.
required: false
default: 1
minimum: 1
type: integer
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
- name: latitude
in: query
description: >
The latitude of a point around which to return posts.
required: false
type: number
- name: longitude
in: query
description: >
The longitude of a point around which to return posts.
required: false
type: number
- name: radius
in: query
description: >
The radius in meters of a circle centered at the point defined by the latitude and longitude parameters.
When latitude, longitude and radius are passed, only posts within the circle defined by these parameters will be returned.
required: false
type: number
minimum: 0
maximum: 257500
- name: date_min
in: query
description: >
Only posts newer than or equal to this UTC date and time will be returned.
required: false
type: string
format: date-time
- name: date_max
in: query
description: Only posts older than this UTC date and time will be returned.
required: false
type: string
format: date-time
- name: outcomes
in: query
type: string
required: false
default: ''
description: >
A comma separated list of the post outcomes to return. The available post outcomes are: satisfied, withdrawn
There are also a couple special values that can be passed.
If set to an empty string (the default), only posts that are not satisfied and not withdrawn and not expired are returned.
If set to 'all', all posts will be returned no matter what outcome the posts have.
If set to 'not-promised', only posts that are not satisfied ant not withdrawn and not expired and not promised are returned.
#
- name: include_reposts
in: query
description: >
If set to 1 (the default), posts that are reposts will be included.
If set to 0, reposts will be excluded.
See the repost_count field of post objects for details about how reposts are identified.
required: false
default: 1
minimum: 0
maximum: 1
type: integer
responses:
200:
description: The posts and paging data.
schema:
type: object
properties:
posts:
type: array
items:
$ref: "#/definitions/PostSearchResult"
num_posts:
type: integer
description: The total number of posts available.
page:
type: integer
description: The page number of the posts being returned.
per_page:
type: integer
description: The number of posts being returned per page.
num_pages:
type: integer
description: The total number of pages available.
start_index:
type: integer
description: The index of the first post being returned (an integer between 1 and num_posts).
end_index:
type: integer
description: The index of the last post being returned (an integer between start_index and num_posts).
group_ids:
type: array
items:
type: string
description: >
The IDs of the groups that the posts were retrieved from (will be null when no group IDs were used).
These IDs may be a subset of the requested group IDs when a request includes group IDs for groups
that are not open archives and that the current user is not a member of. If the open_archive_groups
source is used, these IDs may include the IDs of open archive groups that weren't present in the
group_ids parameter of the request.
400:
description: Missing or invalid parameters.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
/users/{user_id}/feedback:
# get:
# tags:
# - users
# summary: Retrieve feedback about a user
# operationId: get_user_feedback
# produces:
# - application/json
# parameters:
# - name: user_id
# in: path
# description: A user ID.
# required: true
# type: string
# responses:
# 200:
# description: Feedback data about the
# schema:
# type: object
# properties:
# feedback:
# type: array
# items:
# $ref: "#/definitions/Feedback"
# reviewers:
# type: object
# additionalProperties:
# type: string
# description: >
# All the Users who are referenced by their user_id's in the feedback array are returned is this JSON object.
# The JSON object is a map from each User's user_id to the User data.
# score:
# type: integer
# description: The feedback score of the user (may be null). See User definition for more details.
# percent_positive:
# type: number
# description: >
# The percent of feedback that the user has received in the last year that was positive (may be null).
# See User definition for more details.
# # totals:
# # type: object
# # properties:
# # all:
# # type: object
# # properties:
# # total:
# # type: integer
# # description: The total count of feedback that the user has received over all time.
# # positive:
# # type: integer
# # description: The total count of positive feedback that the user has received over all time.
# # negative:
# # type: integer
# # description: The total count of negative feedback that the user has received over all time.
# 404:
# description: User not found.
post:
tags:
- users
summary: Submit feedback on a user
description: >
Allows the current user to submit feedback on a user. The current user can only leave feedback
on a user if the feedback allowed property on that user is set to true (see User definition for more details).
And the system will only store the most recent feedback submission that the current user has submitted on a user.
If the current user submits feedback multiple times, the newest feedback will overwrite the older feedback.
This allows users to update their feedback as long as the feedback allowed property allows it.
operationId: submit_user_feedback
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: user_id
in: path
description: A user ID.
required: true
type: string
- name: positive
in: formData
description: If set to 1, the feedback is positive. If set to 0, the feedback is negative.
required: true
type: integer
- name: content
in: formData
description: >
A comment written by the current user about the user they are leaving feedback on.
This is optional for positive feedback but is required for negative feedback.
required: false
type: string
maxLength: 16384
- name: category
in: formData
description: >
For positive feedback, category should not be set.
For negative feedback, category should be set to one of:
NO_SHOW, UNRESPONSIVE, LATE_OR_TOO_EARLY, ITEM_NOT_AS_DESCRIBED, BROKEN_PROMISE, RUDE, RESELLER, SELLING, UNWANTED_MESSAGES, COMMUNICATION, OTHER
Below are descriptions for each of these categories:
**NO_SHOW** - The user did not show up when they said they would.
**UNRESPONSIVE** - The user failed to respond when a response was expected.
**LATE_OR_TOO_EARLY** - The user showed up later than they said they would (or too early).
**ITEM_NOT_AS_DESCRIBED** - The user gave away an item that had a misleading on incomplete description.
**BROKEN_PROMISE** - The user broke a promise.
**RUDE** - The user was rude or impolite.
**RESELLER** - The user is obtaining free items to sell on other sites without disclosing their intent to resell.
**SELLING** - The user is selling items on trash nothing.
**UNWANTED_MESSAGES** - The user is sending off-topic or unrelated messages.
**COMMUNICATION** - The users' communication is unclear, confusing or bad.
**OTHER** - This category is for anything that does not fit in any of the above categories.
required: false
type: string
responses:
200:
description: The updated user and feedback.
schema:
type: object
properties:
user:
$ref: "#/definitions/User"
feedback:
$ref: "#/definitions/Feedback"
400:
description: Missing or invalid parameters.
404:
description: User not found.
delete:
tags:
- users
summary: Remove feedback on a user
description: >
Allows the current user to remove feedback that they left on a user.
operationId: remove_user_feedback
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: user_id
in: path
description: A user ID.
required: true
type: string
responses:
200:
description: The updated user.
schema:
type: object
properties:
user:
$ref: "#/definitions/User"
400:
description: Missing or invalid parameters.
404:
description: User not found.
/users/me/groups:
get:
tags:
- users
summary: List current users' groups
operationId: get_current_user_groups
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: membership
in: query
description: >
Set the membership parameter to only return certain groups.
The options are:
- **subscribed**: Only return groups the user is a member of.
- **pending-questions**: Only return groups where the user needs to respond to a new member questionnaire.
- **pending**: Only return groups where the user is waiting for their membership request to be approved (excludes groups which are pending-questions).
If unset, all groups the user is a member of and pending membership on will be returned.
required: false
type: string
responses:
200:
description: The users groups.
schema:
type: array
items:
$ref: "#/definitions/Group"
400:
description: Invalid membership parameter.
/users/me/notices:
get:
tags:
- users
summary: List current users' group notices
operationId: get_user_group_notices
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: group_ids
in: query
description: A comma separated list of group IDs to return notices for. If unset, notices for all the users groups will be returned.
required: false
type: string
responses:
200:
description: The users group notices.
schema:
type: array
items:
$ref: "#/definitions/GroupNotice"
400:
description: Invalid group IDs.
/users/{user_id}/profile-image:
get:
tags:
- users
summary: Retrieve a users' profile image
description: >
This is designed to be used as the src attribute
of an HTML <img> tag to show the profile image of the given user.
operationId: get_profile_image_file
produces:
- image/jpeg
- image/png
- image/gif
parameters:
- name: user_id
in: path
description: The user ID of the user to return the profile image of.
required: true
type: string
- name: default
in: query
description: >
A default image URL to use when the user has no profile image.
Or to use one of the Gravatar default images, you can set default to
any one of (404, mm, identicon, monsterid, wavatar, retro, blank).
To learn how the Gravatar default images options work, see the Default Image section on the page at:
https://en.gravatar.com/site/implement/images/
required: false
type: string
responses:
302:
description: >
This endpoint returns an HTTP redirect to a URL that hosts the image.
So requests on this endpoint that automatically follow redirects (eg. most browsers)
will be redirected to a valid image file.
400:
description: Invalid default parameter.
/users/me/profile-image:
post:
tags:
- users
summary: Set a profile image
operationId: set_profile_image
description: >
Profile images must be at least 90 pixels wide and tall. And if the image used is not square
it will be automatically cropped to be square.
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: photo
in: formData
description: Photo to upload.
required: false
type: file
- name: photo_id
in: formData
required: false
type: string
description: Photo to use (if already uploaded).
- name: set_default
in: formData
required: false
type: integer
description: >
Whether or not to set the photo as the users' default profile image. Set to 1 to enable and 0 to disable.
default: 1
- name: crop
in: formData
required: false
type: string
description: >
If the photo needs to be cropped, a JSON encoded object with the crop arguments can be passed.
The supported crop arguments are below. All arguments except rotate are required.
- **original_width**: Original width of the photo before being cropped or rotated (in pixels).
- **original_height**: Original height of the photo before being cropped or rotated (in pixels).
- **x**: The x-coordinate of the top left corner of the cropped area.
- **y**: The y-coordinate of the top left corner of the cropped area.
- **size**: The size of the square cropped area.
- **rotate**: (optional) The number of degrees to rotate the image before cropping.
Currently only 90, 180 and 270 are supported which correspond to rotate left, rotate upside down and rotate right.
- name: device_pixel_ratio
in: formData
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
responses:
200:
description: The updated user and the photo.
schema:
type: object
properties:
user:
$ref: "#/definitions/CurrentUser"
description: The updated user.
photo:
$ref: "#/definitions/PhotoResult"
description: The resulting photo.
400:
description: Missing or invalid parameters.
/users/me/profile-images:
get:
tags:
- users
summary: List current users' profile images
operationId: get_profile_images
produces:
- application/json
responses:
200:
description: The users profile images.
schema:
type: array
items:
type: object
properties:
image:
type: string
description: An image URL.
source:
type: string
description: >
The source of the image. Currently one of: gravatar, facebook, google
NOTE: Additional sources may be added in the future (eg. 'trashnothing' when support
for uploading custom profile images is added) so clients should take care to support arbitrary
sources being returned.
/users/me/post-locations:
get:
tags:
- users
summary: List current users' post locations
description: Only the most recent 3 post locations are returned.
operationId: get_post_locations
produces:
- application/json
responses:
200:
description: The current users' post locations.
schema:
type: array
items:
type: object
properties:
name:
type: string
description: The location name used when submitting new posts.
latitude:
type: number
longitude:
type: number
put:
tags:
- users
summary: Save a post location for the current user
description: >
Creates or updates a post location for the current user.
Updates will happen when the name of the post location matches a previous post location.
operationId: save_post_location
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: name
in: formData
description: A name that describes the location specified by the given latitude and longitude (must be >= 2 characters and <= 30 characters).
required: true
type: string
- name: latitude
in: formData
required: true
type: number
- name: longitude
in: formData
required: true
type: number
responses:
200:
description: The current users' post locations.
schema:
type: array
items:
type: object
properties:
name:
type: string
description: The location name used when submitting new posts.
latitude:
type: number
longitude:
type: number
/users/me/alerts:
get:
tags:
- users
summary: List current users' email alerts
operationId: get_alerts
produces:
- application/json
responses:
200:
description: The users alerts.
schema:
type: array
items:
$ref: "#/definitions/Alert"
put:
tags:
- users
summary: Create an email alert
operationId: create_alert
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: search
in: formData
description: When a post matches this search query, an email alert will be sent. Must have a length >= 2 and < 255 characters.
required: true
type: string
- name: types
in: formData
description: >
A comma separated list of the post types that the alert should match against.
The available post types are: offer, wanted
required: true
type: string
responses:
200:
description: The new alert.
schema:
$ref: "#/definitions/Alert"
400:
description: Missing or invalid parameters or maximum number of alerts reached.
/users/me/alerts/{alert_id}:
delete:
tags:
- users
summary: Delete an email alert
operationId: delete_alert
produces:
- application/json
parameters:
- name: alert_id
in: path
description: The ID of the email alert to delete.
required: true
type: string
responses:
200:
description: Alert deleted.
403:
description: The user doesn't have permission to access the alert.
404:
description: Alert not found.
#
/users/me/reset-password:
post:
tags:
- users
summary: Send password reset email
operationId: send_password_reset_email
produces:
- application/json
responses:
200:
description: Password reset email was sent.
/users/me/resend-verification:
post:
tags:
- users
summary: Resend account verification email
operationId: resend_account_verification_email
produces:
- application/json
responses:
200:
description: Verification email was resent.
400:
description: Account already verified.
/users/me/location:
put:
tags:
- users
summary: Update location
description: >
Update the current users' location.
The location is used to determine which posts are shown to the user (both public posts and group posts).
operationId: update_location
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: name
in: formData
description: A name that describes the location specified by the given latitude and longitude (must be <= 128 characters).
required: true
type: string
- name: latitude
in: formData
required: true
type: number
- name: longitude
in: formData
required: true
type: number
- name: radius
in: formData
description: >
A radius in meters that defines a circle around the point specified by latitude and longitude.
Only posts within the area specified by this circle will be shown.
If set to 0, effectively disables public posts for the user.
required: true
type: number
minimum: 0
maximum: 257500
responses:
200:
description: The user with the updated location.
schema:
$ref: "#/definitions/CurrentUser"
400:
description: Missing or invalid parameters.
/users/me/email:
post:
tags:
- users
summary: Change email address
description: >
Change the users' current email address. A verification link will be emailed to the new email address to
verify that the email account belongs to the user. The email change will not take effect until the user clicks
the link in the verification email.
operationId: change_email
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: address
in: formData
description: The new email address.
required: true
type: string
responses:
200:
description: A verification email was sent to the new email address.
400:
description: Invalid email address.
/users/me/email/not-bouncing:
put:
tags:
- users
summary: Set users' email address as not bouncing
description: >
Resets an email address bouncing state to false. The users' email address may be automatically marked as bouncing
again if further emails sent to it are bounced.
operationId: set_email_not_bouncing
produces:
- application/json
responses:
200:
description: The updated user.
schema:
$ref: "#/definitions/CurrentUser"
400:
description: Email not yet verified.
/users/report:
post:
tags:
- users
summary: Report a user
operationId: report_user
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: subject
in: formData
description: The subject of the message.
required: false
type: string
- name: message
in: formData
description: The body of the message.
required: true
type: string
- name: user_id
in: formData
description: The ID of the user to report. One of user_id or user_email must be passed but only user_id will be used if both are passed.
required: false
type: string
- name: user_email
in: formData
description: >
The email of the user to report. Often users only know to identify other users by their email addresses
so allowing users to enter an email address can be easier in certain cases.
required: false
type: string
- name: group_id
in: formData
description: >
The ID of the group to report the user to. This may be disregarded in cases where user_email is set
and can be used to automatically identify which group the user should be reported to (because some email
addresses are specific to certain groups).
required: false
type: string
responses:
200:
description: The user was reported.
400:
description: Missing or invalid parameters. In particular, a user cannot report themselves.
404:
description: User or group not found.
/feedback:
post:
tags:
- misc
summary: Send feedback
description: Allows users to send feedback about the trashnothing.com site or apps.
operationId: send_feedback
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: subject
in: formData
description: The subject.
required: true
type: string
- name: message
in: formData
description: The message.
required: true
type: string
- name: meta
in: formData
description: >
Extra information set by the client that may be useful to contextualize the feedback
(eg. operating system details, browser details, app details, device details).
required: false
type: string
responses:
200:
description: The feedback has been sent.
#
/stories:
get:
tags:
- stories
summary: List stories
operationId: get_stories
produces:
- application/json
parameters:
- name: page
in: query
description: The page of stories to return.
required: false
default: 1
minimum: 1
type: integer
- name: per_page
in: query
description: The number of stories to return per page (must be >= 1 and <= 50).
required: false
default: 20
minimum: 1
maximum: 50
type: integer
- name: sort_by
in: query
description: >
How to sort the stories that are returned. One of: date, distance, likes, views
Setting sort_by to date will sort posts from newest to oldest. Setting sort_by to distance
will sort posts from nearest to farthest. Setting sort_by to likes will sort posts with the most
likes first. Setting sort_by to views will show the posts with the most views first.
required: false
default: date
type: string
- name: latitude
in: query
description: Find groups near the given latitude and longitude.
required: false
type: number
- name: longitude
in: query
description: Find groups near the given latitude and longitude.
required: false
type: number
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
responses:
200:
description: The stories and paging data.
schema:
type: object
properties:
stories:
type: array
items:
$ref: "#/definitions/Story"
#
400:
description: Missing or invalid parameters.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
post:
tags:
- stories
summary: Submit a story
operationId: submit_story
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: title
in: formData
description: The title of the story.
required: true
type: string
maxLength: 80
- name: content
in: formData
description: The content of the story.
required: true
type: string
- name: sharing
in: formData
description: >
Must be set to one of the following two options: public, members
When sharing is set to public, anyone will be able to view the story.
When sharing is set to members, only other members will be able to view the story.
required: true
type: string
- name: photo_ids
in: formData
description: A comma separated list of the IDs of the photos that should be attached to this story.
required: false
type: string
- name: device_pixel_ratio
in: formData
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
responses:
200:
description: The new story.
schema:
$ref: "#/definitions/Story"
400:
description: Missing or invalid parameters.
/stories/{story_id}:
get:
tags:
- stories
summary: Retrieve a story
operationId: get_story
produces:
- application/json
parameters:
- name: story_id
in: path
description: The ID of the story to retrieve.
required: true
type: string
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
responses:
200:
description: The story.
schema:
$ref: "#/definitions/Story"
403:
description: Story is only visible to members.
404:
description: Story not found.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
/stories/{story_id}/like:
put:
tags:
- stories
summary: Like a story
operationId: like_story
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: story_id
in: path
description: The ID of the story to like.
required: true
type: string
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
responses:
200:
description: The updated story.
schema:
$ref: "#/definitions/Story"
404:
description: Story not found.
/stories/{story_id}/unlike:
put:
tags:
- stories
summary: Unlike a story
operationId: unlike_story
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: story_id
in: path
description: The ID of the story to unlike.
required: true
type: string
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
responses:
200:
description: The updated story.
schema:
$ref: "#/definitions/Story"
404:
description: Story not found.
/stories/{story_id}/viewed:
post:
tags:
- stories
summary: Record story viewed
description: Records every time a user views the full story (and not just a preview or snippet),
operationId: viewed_story
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: story_id
in: path
description: The ID of the story viewed.
required: true
type: string
responses:
200:
description: Story view was recorded.
404:
description: Story not found.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
/groups:
get:
tags:
- groups
summary: Search groups
operationId: search_groups
produces:
- application/json
parameters:
- name: name
in: query
description: Find groups that have the given text somewhere in their name (case insensitive).
required: false
type: string
- name: latitude
in: query
description: Find groups near the given latitude and longitude.
required: false
type: number
- name: longitude
in: query
description: Find groups near the given latitude and longitude.
required: false
type: number
- name: distance
in: query
description: >
When latitude and longitude are passed, distance can optionally be passed to only
return groups within a certain distance (in kilometers) from the point specified
by the latitude and longitude. The distance must be > 0 and <= 150 and will
default to 100.
required: false
default: 100
minimum: 0
maximum: 150
type: number
- name: country
in: query
description: >
Find groups in the given country where country is a 2 letter country code for the
country (see https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 ).
required: false
type: string
- name: region
in: query
description: >
For countries with regions (AU, CA, GB, US), search groups in a specific region as
specified by the region abbreviation. The supported regions and their abbreviations are listed below.
NOTE: The region and postal_code parameters cannot be used at the same time and if both
are passed then the postal_code will take priority.
---
**AU**
- QLD: Queensland
- SA: South Australia
- TAS: Tasmania
- VIC: Victoria
- WA: Western Australia
- NT: Northern Territory
- NSW: New South Wales - ACT
**CA**
- AB: Alberta
- BC: British Columbia
- MB: Manitoba
- NB: New Brunswick
- NL: Newfoundland and Labrador
- NS: Nova Scotia
- ON: Ontario
- QC: Quebec
- SK: Saskatchewan
- PE: Prince Edward Island
**GB**
- E: East
- EM: East Midlands
- LDN: London
- NE: North East
- NW: North West
- NI: Northern Ireland
- SC: Scotland
- SE: South East
- SW: South West
- WA: Wales
- WM: West Midlands
- YH: Yorkshire and the Humber
**US**
All 50 states and the District of Columbia are supported. For the abbreviations, see:
https://github.com/jasonong/List-of-US-States/blob/master/states.csv
required: false
type: string
- name: postal_code
in: query
description: >
Find groups in the given postal code. Only a few countries support postal code
searches (US, CA, AU, GB). The country parameter must be passed when the
postal_code parameter is set.
NOTE: The region and postal_code parameters cannot be used at the same time and if both
are passed then the postal_code will take priority.
required: false
type: string
- name: page
in: query
description: The page of groups to return.
required: false
default: 1
minimum: 1
type: integer
- name: per_page
in: query
description: The number of groups to return per page (must be >= 1 and <= 100).
required: false
default: 20
minimum: 1
maximum: 100
type: integer
responses:
200:
description: The groups and paging data.
schema:
type: object
properties:
groups:
type: array
items:
$ref: "#/definitions/Group"
num_groups:
type: integer
description: The total number of groups available.
page:
type: integer
description: The page number of the groups being returned.
per_page:
type: integer
description: The number of groups being returned per page.
num_pages:
type: integer
description: The total number of pages available.
start_index:
type: integer
description: The index of the first group being returned (an integer between 1 and num_groups).
end_index:
type: integer
description: The index of the last group being returned (an integer between start_index and num_groups).
400:
description: Missing or invalid parameters.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
/groups/{group_id}:
get:
tags:
- groups
summary: Retrieve a group
operationId: get_group
produces:
- application/json
parameters:
- name: group_id
in: path
description: The ID of the group to retrieve.
required: true
type: string
responses:
200:
description: The group.
schema:
$ref: "#/definitions/Group"
404:
description: Group not found.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
/groups/multiple:
get:
tags:
- groups
summary: Retrieve multiple groups
operationId: get_groups_by_ids
produces:
- application/json
parameters:
- name: group_ids
in: query
description: The IDs of the groups to retrieve. If more than 20 group IDs are passed, only the first 20 groups will be returned.
required: true
type: string
responses:
200:
description: The groups.
schema:
type: array
items:
$ref: "#/definitions/Group"
400:
description: Missing or invalid parameters.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
/groups/subscribe:
post:
tags:
- groups
summary: Join groups
description: >
Request membership to one or more groups.
NOTE: Any group with a has_questions field set to true will also require answers to the groups' new member questionnaire to be
submitted. Groups waiting for answers will have their membership field set to 'pending-questions'. And the questionnaire
that needs to be answered can be found in the membership.questionnaire field of the group after a subscribe request is made
to that group.
operationId: join_groups
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: group_ids
in: formData
description: A comma separated list of the IDs of the groups to join.
required: true
type: string
responses:
200:
description: The groups with updated membership data.
schema:
type: object
properties:
groups:
type: array
description: Updated data about the groups and the current users' membership to each group.
items:
$ref: "#/definitions/Group"
over_group_limit:
type: boolean
description: >
When this is true, it means that some of the membership requests weren't processed in order to keep
the user from going over the 12 group limit (the membership field of the groups can be used
to determine which requests were processed).
400:
description: Missing or invalid parameters.
404:
description: Group not found.
/groups/{group_id}/unsubscribe:
post:
tags:
- groups
summary: Leave a group
operationId: leave_group
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: group_id
in: path
description: The ID of the group to leave.
required: true
type: string
responses:
200:
description: Updated data about the group and the current users' membership.
schema:
$ref: "#/definitions/Group"
400:
description: The current user is not an active or pending member of the given group.
404:
description: Group not found.
/groups/{group_id}/contact:
post:
tags:
- groups
summary: Contact group moderators
operationId: contact_moderators
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: group_id
in: path
description: The group ID of the group whose moderators will be contacted.
required: true
type: string
- name: subject
in: formData
description: The subject of the message.
required: true
type: string
- name: message
in: formData
description: The body of the message.
required: true
type: string
responses:
200:
description: Message was sent to moderators.
400:
description: Missing or invalid parameters.
404:
description: Group not found.
#
/groups/{group_id}/answers:
post:
tags:
- groups
summary: Submit group answers
# XXX: body parameter description only placed here b/c ReDoc doesn't display it properly with the parameter like swagger UI does
description: >
Submits answers to a groups' membership questionnaire.
The request body should be a JSON object mapping each question from the group membership.questionnaire.questions field to an answer
(eg. {"Where do you live?": "New York City"} ).
All questions are required so no null or empty string answers are allowed.
operationId: submit_answers
consumes:
- application/json
produces:
- application/json
parameters:
- name: group_id
in: path
description: The group ID of the group that the user is submitting answers for.
required: true
type: string
- name: body
in: body
description: >
A JSON object mapping each question from the group membership.questionnaire.questions field to an answer
(eg. {"Where do you live?": "New York City"} ).
All questions are required so no null or empty string answers are allowed.
required: true
schema:
type: object
additionalProperties:
type: string
responses:
200:
description: The updated group.
schema:
$ref: "#/definitions/Group"
400:
description: Missing or invalid answers or questions were already answered or questions don't need to be answered.
404:
description: Group not found.
/posts:
get:
tags:
- posts
summary: List posts
description: >
NOTE: When paging through the posts returned by this endpoint, there will be at most 1,000 posts that can be
returned (eg. 50 pages worth of posts with the default per_page value of 20). In areas where there are more
than 1,000 posts, clients can use more specific query parameters to adjust which posts are returned.
NOTE: Passing the latitude, longitude and radius parameters filters all posts by their location and so these
parameters will temporarily override the current users' location preferences.
When latitude, longitude and radius are not specified, public posts will be filtered by the current users'
location preferences.
operationId: get_posts
produces:
- application/json
parameters:
- name: sort_by
in: query
description: >
How to sort the posts that are returned. One of: date, active, distance
Date sorting will sort posts from newest to oldest.
Active sorting will sort active posts before satisfied, withdrawn and expired posts and then sort by date.
Distance sorting will sort the closest posts first.
required: false
default: date
type: string
- name: types
in: query
description: >
A comma separated list of the post types to return. The available post types are: offer, taken, wanted, received, admin
required: true
type: string
- name: sources
in: query
description: >
A comma separated list of the post sources to retrieve posts from. The available sources are:
groups, trashnothing, open_archive_groups.
The trashnothing source is for public posts that are posted on trash nothing but are not associated with any group.
The open_archive_groups source provides a way to easily request posts from groups that have open_archives set to true
without having to pass a group_ids parameter. When passed, it will automatically return posts from open archive groups
that are within the area specified by the latitude, longitude and radius parameters
(or the current users' location if
latitude, longitude and radius aren't passed).
NOTE: For requests using an api key instead of oauth, passing the trashnothing source or the open_archive_groups source
makes the latitude, longitude and radius parameters required.
required: true
type: string
- name: group_ids
in: query
description: >
A comma separated list of the group IDs to retrieve posts from.
This parameter is only used if the 'groups' source is passed in the sources parameter
and only groups that the current user is a member of or that are open archives groups
will be used (the group IDs of other groups will be silently discarded*).
NOTE: For requests using an api key instead of oauth, this field is required if the 'groups' source is passed.
In addition, only posts from groups that have open_archives set to true will be used
(the group IDS of other groups will be silently discarded*).
*To determine which group IDs were used and which were discarded, use the group_ids field in the response.
required: false
default: The group IDs of every group the current user is a member of.
type: string
- name: per_page
in: query
description: The number of posts to return per page (must be >= 1 and <= 100).
required: false
default: 20
minimum: 1
maximum: 100
type: integer
- name: page
in: query
description: The page of posts to return.
required: false
default: 1
minimum: 1
type: integer
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
- name: latitude
in: query
description: >
The latitude of a point around which to return posts.
required: false
type: number
- name: longitude
in: query
description: >
The longitude of a point around which to return posts.
required: false
type: number
- name: radius
in: query
description: >
The radius in meters of a circle centered at the point defined by the latitude and longitude parameters.
When latitude, longitude and radius are passed, only posts within the circle defined by these parameters will be returned.
required: false
type: number
minimum: 0
maximum: 257500
- name: date_min
in: query
description: >
Only posts newer than or equal to this UTC date and time will be returned. If unset, defaults to the current date and time minus 90 days.
required: false
type: string
format: date-time
- name: date_max
in: query
description: Only posts older than this UTC date and time will be returned. If unset, defaults to the current date and time.
required: false
type: string
format: date-time
- name: outcomes
in: query
type: string
required: false
default: ''
description: >
A comma separated list of the post outcomes to return. The available post outcomes are: satisfied, withdrawn
There are also a couple special values that can be passed.
If set to an empty string (the default), only posts that are not satisfied and not withdrawn and not expired are returned.
If set to 'all', all posts will be returned no matter what outcome the posts have.
If set to 'not-promised', only posts that are not satisfied ant not withdrawn and not expired and not promised are returned.
#
- name: user_state
in: query
type: string
required: false
default: ''
description: >
If user_state is set, only posts matching the state specified will be returned. Only one state may be passed
and it must be one of the following: viewed, replied, bookmarked
NOTE: This option will only work with oauth requests.
- name: include_reposts
in: query
description: >
If set to 1 (the default), posts that are reposts will be included.
If set to 0, reposts will be excluded.
See the repost_count field of post objects for details about how reposts are identified.
required: false
default: 1
minimum: 0
maximum: 1
type: integer
responses:
200:
description: The posts and paging data.
schema:
type: object
properties:
posts:
type: array
items:
$ref: "#/definitions/Post"
num_posts:
type: integer
description: The total number of posts available.
page:
type: integer
description: The page number of the posts being returned.
per_page:
type: integer
description: The number of posts being returned per page.
num_pages:
type: integer
description: The total number of pages available.
start_index:
type: integer
description: The index of the first post being returned (an integer between 1 and num_posts).
end_index:
type: integer
description: The index of the last post being returned (an integer between start_index and num_posts).
group_ids:
type: array
items:
type: string
description: >
The IDs of the groups that the posts were retrieved from (will be null when no group IDs were used).
These IDs may be a subset of the requested group IDs when a request includes group IDs for groups
that are not open archives and that the current user is not a member of. If the open_archive_groups
source is used, these IDs may include the IDs of open archive groups that weren't present in the
group_ids parameter of the request.
last_listings_view:
type: string
format: date-time
description: >
The UTC date and time when the current user last viewed the newest posts on the All Posts page (may be null).
NOTE: For this to be accurate, clients must update the last_listings_view property of the current user every time the user is shown
the newest posts on the All Posts page.
NOTE: For requests using an api key instead of oauth, this field is always null.
400:
description: Missing or invalid parameters.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
post:
tags:
- posts
summary: Submit a post
description: >
Submits a new post.
operationId: submit_post
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: group_ids
in: formData
description: A comma separated list of group IDs to submit the post to (if any).
required: false
type: string
- name: type
in: formData
description: >
The type of post. One of: offer, wanted
required: true
type: string
- name: title
in: formData
description: A short description of the item(s).
required: true
type: string
minLength: 2
maxLength: 35
- name: location
in: formData
description: A short location description.
required: true
type: string
minLength: 2
maxLength: 30
- name: content
in: formData
description: A longer description of the item(s).
required: false
type: string
- name: fair_offer
in: formData
description: If set to 1, the post will be posted with the Fair Offer Policy (only valid for offer posts - see https://trashnothing.com/fair_offer_policy ).
required: false
type: integer
default: 0
- name: latitude
in: formData
description: >
The latitude corresponding to the location description provided.
If latitude and longitude are not provided, an attempt will be made to automatically geocode the
location. If the location is unable to be geocoded, the post will be rejected* and will have to
be resubmitted with a latitude and longitude corresponding to the location
or resubmitted with a different location that can be automatically geocoded.
NOTE: The latitude and longitude should NOT be the users' exact location because we don't want to publicize
their exact location unless their location description is their full address (which is not recommended).
*When a post is rejected because it can't be geocoded, the returned error will have its
identifier property set to 'unknown-location'.
required: false
type: number
- name: longitude
in: formData
description: The longitude corresponding to the location description provided. (see the NOTE in latitude description)
required: false
type: number
- name: photo_ids
in: formData
description: A comma separated list of the IDs of the photos that should be attached to this post.
required: false
type: string
- name: expires_in
in: formData
description: >
When the post should expire. Defaults to 90 days.
Any amount of time from 1 hour to 90 days can be provided.
To pass a number of hours, provide the number of hours prefixed by 'h' (eg. 1hr 24hr).
To pass a number of days, provide the number of days prefixed by 'd' (eg. 1d 90d).
Note that posts may not appear instantly after submission
because the volunteer moderators of many groups may have additional automatic or manual review processes in place
that can cause delays. So with short expirations (eg. < 8 hours), there is a chance that
the post may expire before it's
approved and so it will never be published.
required: false
type: string
- name: reselling
in: formData
description: >
For wanted posts only. If set to 1, the wanted post will show that the poster intends to resell
any items that they receive in response to this post. Posters must declare if they intend to resell
items.
required: false
type: string
- name: repost
in: formData
description: >
If the post is a repost of an existing post, this should be set to the post_id of the post that is being reposted.
required: false
type: string
- name: session
in: formData
description: >
A JSON string representing a temporary object that is used to store data about the submission
process for a single post. The first time a post is submitted, session should
be a new empty object (eg. '{}'). The session object should be persisted by the client until
that post is successfully submitted and then it
can be discarded so that the next post will start
over with a new empty session object. Every time a post is submitted and the response
indicates that the submission was not successful, the session object returned in the response
should override the clients copy of the session.
required: true
type: string
- name: preferences
in: formData
description: >
A JSON string representing a permanent object that the client persists and modifies based on
warnings returned by the post
submission process and user input. Some warnings returned after submitting
a post have a preference_key
string property so that users can opt out of those warnings in the future. To save this opt-out
preference, set the property indicated by the preference_key in the preferences object
(eg. preferences[preference_key] = 1). The preferences object is never modified by the server -
it is up to the client to initialize, modify and persist the preferences object.
required: false
type: string
responses:
200:
description: Post submission result.
schema:
type: object
properties:
result:
type: string
description: >
One of: success, error, warning.
A success result indicates that the post was submitted successfully.
Note that posts may not appear instantly after submission
because the volunteer moderators of many groups may have additional
automatic or manual review processes in place that can cause delays.
An error result indicates that there is an error with the post that should be shown to the user and the message property
will contain text describing the error.
A warning result indicates that there is a warning about the post
to show the user and the message property will contain a string describing the warning.
A warning result doesn't prevent a post from
being submitted, to continue the submission process after a warning result, just re-submit
(with the updated session object) to temporarily override that specific warning.
message:
type: string
description: >
Contains text describing the reason a post was not successful. Is null on success.
preference_key:
type: string
description: >
Certain types of warnings can be opted out of. These warnings will set preference_key to a string that can be
set in the preferences object by the client to opt out of that type of warning in the future (see the description
of the preferences parameter for more details). Is null for errors, success and warnings that can't be opted out of.
session:
type: object
description: >
The updated session object that should override the client's copy of the session that was passed in the session parameter.
Is null on success.
additionalProperties:
type: string
identifier:
type: string
description: >
When an error or warning is returned, this will contain a short string representing the type of error or warning
that occurred. Is null on success.
# XXX: would be nice to return a post for display on Your Posts page.. but there's so much processing/deduplicating that is done..
400:
description: Missing or invalid parameters.
/posts/search:
get:
tags:
- posts
summary: Search posts
description: >
Searching posts takes the same arguments as listing posts except for the addition of the search and sort_by parameters.
NOTE: When paging through the posts returned by this endpoint, there will be at most 1,000 posts that can be
returned (eg. 50 pages worth of posts with the default per_page value of 20). In areas where there are more
than 1,000 posts, clients can use more specific query parameters to adjust which posts are returned.
operationId: search_posts
produces:
- application/json
parameters:
- name: search
in: query
description: The search query used to find posts.
required: true
type: string
- name: sort_by
in: query
description: >
How to sort the posts that are returned. One of: relevance, date, active, distance
Relevance sorting will sort the posts that best match the search query first.
Date sorting will sort posts from newest to oldest.
Active sorting will sort active posts before satisfied, withdrawn and expired posts and then sort by date.
Distance sorting will sort the closest posts first.
required: false
default: relevance
type: string
- name: types
in: query
description: >
A comma separated list of the post types to return. The available post types are: offer, taken, wanted, received, admin
required: true
type: string
- name: sources
in: query
description: >
A comma separated list of the post sources to retrieve posts from. The available sources are:
groups, trashnothing, open_archive_groups.
The trashnothing source is for public posts that are posted on trash nothing but are not associated with any group.
The open_archive_groups source provides a way to easily request posts from groups that have open_archives set to true
without having to pass a group_ids parameter. When passed, it will automatically return posts from open archive groups
that are within the area specified by the latitude, longitude and radius parameters
(or the current users' location if
latitude, longitude and radius aren't passed).
NOTE: For requests using an api key instead of oauth, passing the trashnothing source or the open_archive_groups source
makes the latitude, longitude and radius parameters required.
required: true
type: string
- name: group_ids
in: query
description: >
A comma separated list of the group IDs to retrieve posts from.
This parameter is only used if the 'groups' source is passed in the sources parameter
and only groups that the current user is a member of or that are open archives groups
will be used (the group IDs of other groups will be silently discarded*).
NOTE: For requests using an api key instead of oauth, this field is required if the 'groups' source is passed.
In addition, only posts from groups that have open_archives set to true will be used
(the group IDS of other groups will be silently discarded*).
*To determine which group IDs were used and which were discarded, use the group_ids field in the response.
required: false
default: The group IDs of every group the current user is a member of.
type: string
- name: per_page
in: query
description: The number of posts to return per page (must be >= 1 and <= 100).
required: false
default: 20
minimum: 1
maximum: 100
type: integer
- name: page
in: query
description: The page of posts to return.
required: false
default: 1
minimum: 1
type: integer
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
- name: latitude
in: query
description: >
The latitude of a point around which to return posts.
required: false
type: number
- name: longitude
in: query
description: >
The longitude of a point around which to return posts.
required: false
type: number
- name: radius
in: query
description: >
The radius in meters of a circle centered at the point defined by the latitude and longitude parameters.
When latitude, longitude and radius are passed, only posts within the circle defined by these parameters will be returned.
required: false
type: number
minimum: 0
maximum: 257500
- name: date_min
in: query
description: >
Only posts newer than or equal to this UTC date and time will be returned. If unset, defaults to the current date and time minus 90 days.
required: false
type: string
format: date-time
- name: date_max
in: query
description: Only posts older than this UTC date and time will be returned. If unset, defaults to the current date and time.
required: false
type: string
format: date-time
- name: outcomes
in: query
type: string
required: false
default: ''
description: >
A comma separated list of the post outcomes to return. The available post outcomes are: satisfied, withdrawn
There are also a couple special values that can be passed.
If set to an empty string (the default), only posts that are not satisfied and not withdrawn and not expired are returned.
If set to 'all', all posts will be returned no matter what outcome the posts have.
If set to 'not-promised', only posts that are not satisfied ant not withdrawn and not expired and not promised are returned.
#
- name: user_state
in: query
type: string
required: false
default: ''
description: >
If user_state is set, only posts matching the state specified will be returned. Only one state may be passed
and it must be one of the following: viewed, replied, bookmarked
NOTE: This option will only work with oauth requests.
- name: include_reposts
in: query
description: >
If set to 1 (the default), posts that are reposts will be included.
If set to 0, reposts will be excluded.
See the repost_count field of post objects for details about how reposts are identified.
required: false
default: 1
minimum: 0
maximum: 1
type: integer
responses:
200:
description: The posts and paging data.
schema:
type: object
properties:
posts:
type: array
items:
$ref: "#/definitions/PostSearchResult"
num_posts:
type: integer
description: The total number of posts available.
page:
type: integer
description: The page number of the posts being returned.
per_page:
type: integer
description: The number of posts being returned per page.
num_pages:
type: integer
description: The total number of pages available.
start_index:
type: integer
description: The index of the first post being returned (an integer between 1 and num_posts).
end_index:
type: integer
description: The index of the last post being returned (an integer between start_index and num_posts).
group_ids:
type: array
items:
type: string
description: >
The IDs of the groups that the posts were retrieved from (will be null when no group IDs were used).
These IDs may be a subset of the requested group IDs when a request includes group IDs for groups
that are not open archives and that the current user is not a member of. If the open_archive_groups
source is used, these IDs may include the IDs of open archive groups that weren't present in the
group_ids parameter of the request.
400:
description: Missing or invalid parameters.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
/posts/all:
get:
tags:
- posts
summary: List all posts
description: >
This endpoint provides an easy way to get a feed of all the publicly published posts on trash nothing.
It provides access to all publicly published offer and wanted posts from the last 30 days.
The posts are sorted by date (newest first).
There are fewer options for filtering, sorting and searching posts with this endpoint but there is no 1,000 post limit and
posts that are crossposted to multiple groups are not merged together in the response. In most
cases, crossposted posts are easy to detect because they have the same user_id, title and content.
operationId: get_all_posts
produces:
- application/json
parameters:
- name: types
in: query
description: >
A comma separated list of the post types to return. The available post types are: offer, wanted
required: true
type: string
- name: date_min
in: query
description: >
Only posts newer than or equal to this UTC date and time will be returned.
The UTC date and time used must be within a day or less of date_max.
And the date and time must be within the last 30 days.
And the date and time must be rounded to the nearest second.
required: true
type: string
format: date-time
- name: date_max
in: query
description: >
Only posts older than this UTC date and time will be returned.
The UTC date and time used must be within a day or less of date_min.
And the date and time must be rounded to the nearest second.
required: true
type: string
format: date-time
- name: per_page
in: query
description: The number of posts to return per page (must be >= 1 and <= 50).
required: false
default: 20
minimum: 1
maximum: 50
type: integer
- name: page
in: query
description: The page of posts to return.
required: false
default: 1
minimum: 1
type: integer
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
responses:
200:
description: The posts.
schema:
type: object
properties:
posts:
type: array
items:
$ref: "#/definitions/Post"
400:
description: Missing or invalid parameters.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
/posts/all/changes:
get:
tags:
- posts
summary: List all post changes
description: >
This endpoint provides an easy way to get a feed of all the changes that have been made to publicly published posts
on trash nothing. Similar to the /posts/all endpoint, only data from the last 30 days is available and the changes
are sorted by date (newest first). Every change includes the date of the change, the post_id of the post that was changed
and the type of change.
The different types of changes that are returned are listed below.
- deleted
- undeleted
- satisfied
- promised
- unpromised
- withdrawn
- edited
For edited changes, clients can use the retrieve post API endpoint to get the edits that have been made to the post.
operationId: get_all_posts_changes
produces:
- application/json
parameters:
- name: date_min
in: query
description: >
Only changes newer than or equal to this UTC date and time will be returned.
The UTC date and time used must be within a day or less of date_max.
And the date and time must be within the last 30 days.
And the date and time must be rounded to the nearest second.
required: true
type: string
format: date-time
- name: date_max
in: query
description: >
Only changes older than this UTC date and time will be returned.
The UTC date and time used must be within a day or less of date_min.
And the date and time must be rounded to the nearest second.
required: true
type: string
format: date-time
- name: per_page
in: query
description: The number of changes to return per page (must be >= 1 and <= 50).
required: false
default: 20
minimum: 1
maximum: 50
type: integer
- name: page
in: query
description: The page of changes to return.
required: false
default: 1
minimum: 1
type: integer
responses:
200:
description: The changes.
schema:
type: object
properties:
changes:
type: array
items:
type: object
properties:
post_id:
type: string
date:
type: string
format: date-time
description: The UTC date and time when the post was changed.
type:
type: string
description: >
The type of change. One of: deleted, undeleted, satisfied, promised, unpromised, withdrawn, edited, expired
400:
description: Missing or invalid parameters.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
/posts/{post_id}/display:
get:
tags:
- posts
summary: Retrieve post display data
description: >
Retrieve a post and other data related to the post that is useful for displaying
the post such as data about the user who posted the post and the groups the post was posted on.
operationId: get_post_and_related_data
produces:
- application/json
parameters:
- name: post_id
in: path
description: The ID of the post to retrieve.
required: true
type: string
responses:
200:
description: The post and related data.
schema:
type: object
properties:
post:
$ref: "#/definitions/Post"
author:
$ref: "#/definitions/User"
author_posts:
type: array
description: >
Other active posts from the post author in the last 90 days.
A maximum of 30 posts will be returned.
items:
$ref: "#/definitions/Post"
author_offer_count:
type: integer
description: Count of offer posts made by the post author in the last 90 days.
author_wanted_count:
type: integer
description: Count of wanted posts made by the post author in the last 90 days.
groups:
type: array
description: The groups the post is published on.
items:
$ref: "#/definitions/Group"
user_can_reply:
type: boolean
description: >
Whether or not the current user (if any) can reply to this post.
Unverified users cannot reply to posts until they verify their account.
feedback:
type: array
description: Feedback the current user has left on the post author.
items:
$ref: "#/definitions/Feedback"
viewed:
type: boolean
description: Whether or not the current user has previously viewed this post. Will be null for api key requests and for the current users' posts.
replied:
type: boolean
description: Whether or not the current user has replied to this post. Will be null for api key requests and for the current users' posts.
bookmarked:
type: boolean
description: Whether or not the current user has bookmarked this post. Will be null for api key requests and for the current users' posts.
403:
description: The user doesn't have permission to access the post.
404:
description: Post not found.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
/posts/{post_id}:
get:
tags:
- posts
summary: Retrieve a post
operationId: get_post
produces:
- application/json
parameters:
- name: post_id
in: path
description: The ID of the post to retrieve.
required: true
type: string
responses:
200:
description: The post.
schema:
$ref: "#/definitions/Post"
403:
description: The user doesn't have permission to access the post.
404:
description: Post not found.
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
put:
tags:
- posts
summary: Update a post
description: >
Users can update posts to fix mistakes with their post, add photos, or add more details about the items.
Updates should not be used to say that items in a post have been taken or received since the
post satisfy endpoint is designed to do that.
operationId: update_post
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: post_id
in: path
description: The ID of the post to update.
required: true
type: string
- name: type
in: formData
description: >
The type of post. One of: offer, wanted
required: true
type: string
- name: title
in: formData
description: A short description of the item(s).
required: true
type: string
minLength: 2
maxLength: 35
- name: location
in: formData
description: A short location description.
required: true
type: string
minLength: 2
maxLength: 30
- name: content
in: formData
description: A longer description of the item(s).
required: false
type: string
- name: fair_offer
in: formData
description: If set to 1, the post will be posted with the Fair Offer Policy (only valid for offer posts - see https://trashnothing.com/fair_offer_policy ).
required: false
type: integer
default: 0
- name: latitude
in: formData
description: >
The latitude corresponding to the location description provided.
If latitude and longitude are not provided, an attempt will be made to automatically geocode the
location. If the location is unable to be geocoded, the post will be rejected* and will have to
be resubmitted with a latitude and longitude corresponding to the location
or resubmitted with a different location that can be automatically geocoded.
NOTE: The latitude and longitude should NOT be the users' exact location because we don't want to publicize
their exact location unless their location description is their full address (which is not recommended).
*When a post is rejected because it can't be geocoded, the returned error will have its
identifier property set to 'unknown-location'.
required: false
type: number
- name: longitude
in: formData
description: The longitude corresponding to the location description provided. (see the NOTE in latitude description)
required: false
type: number
- name: photo_ids
in: formData
description: A comma separated list of the IDs of the photos that should be attached to this post.
required: false
type: string
- name: expires_in
in: formData
description: >
When the post should expire.
Any amount of time from 1 hour to 90 days can be provided.
To pass a number of hours, provide the number of hours prefixed by 'h' (eg. 1hr 24hr).
To pass a number of days, provide the number of days prefixed by 'd' (eg. 1d 90d).
Note that updates may not appear instantly after submission
because the volunteer moderators of many groups may have additional automatic or manual review processes in place
that can cause delays. So with short expirations (eg. < 8 hours), there is a chance that
the post may expire before the update is
approved and so it will never be published.
NOTE: The max expiration for a post is 90 days after the post is published. So updates to posts
that try to set an longer expiration will be silently changed to just apply the max expiration.
required: false
type: string
- name: reselling
in: formData
description: >
For wanted posts only. If set to 1, the wanted post will show that the poster intends to resell
any items that they receive in response to this post. Posters must declare if they intend to resell
items.
required: false
type: string
- name: session
in: formData
description: >
A JSON string representing a temporary object that is used to store data about the update
process for a single post. The first time a post update is submitted, session should
be a new empty object (eg. '{}'). The session object should be persisted by the client until
that update is successfully submitted and then it
can be discarded so that the next update will start
over with a new empty session object. Every time an update is submitted and the response
indicates that the submission was not successful, the session object returned in the response
should override the clients copy of the session.
required: true
type: string
- name: preferences
in: formData
description: >
A JSON string representing a permanent object that the client persists and modifies based on
warnings returned by the update
submission process and user input. Some warnings returned after submitting
an update have a preference_key
string property so that users can opt out of those warnings in the future. To save this opt-out
preference, set the property indicated by the preference_key in the preferences object
(eg. preferences[preference_key] = 1). The preferences object is never modified by the server -
it is up to the client to initialize, modify and persist the preferences object.
required: false
type: string
responses:
200:
description: Post update result.
schema:
type: object
properties:
result:
type: string
description: >
One of: success, error, warning.
A success result indicates that the post update was submitted successfully.
Note that post updates may not appear instantly after submission
because the volunteer moderators of many groups may have additional
automatic or manual review processes in place that can cause delays.
An error result indicates that there is an error with the post that should be shown to the user and the message property
will contain text describing the error.
A warning result indicates that there is a warning about the post update
to show the user and the message property will contain a string describing the warning.
A warning result doesn't prevent a post update from
being submitted, to continue the submission process after a warning result, just re-submit
(with the updated session object) to temporarily override that specific warning.
message:
type: string
description: >
Contains text describing the reason a post update was not successful. Is null on success.
preference_key:
type: string
description: >
Certain types of warnings can be opted out of. These warnings will set preference_key to a string that can be
set in the preferences object by the client to opt out of that type of warning in the future (see the description
of the preferences parameter for more details). Is null for errors, success and warnings that can't be opted out of.
session:
type: object
description: >
The updated session object that should override the client's copy of the session that was passed in the session parameter.
Is null on success.
additionalProperties:
type: string
identifier:
type: string
description: >
When an error or warning is returned, this will contain a short string representing the type of error or warning
that occurred. Is null on success.
400:
description: Missing or invalid parameters.
403:
description: The user doesn't have permission to edit the post.
404:
description: Post not found.
delete:
tags:
- posts
summary: Delete a post
description: >
Users can delete posts they have made that have been satisfied or withdrawn or that have expired.
Deleting posts isn't intended to be a normal part of the posting process since
it makes reposting and viewing old posts harder.
operationId: delete_post
produces:
- application/json
parameters:
- name: post_id
in: path
required: true
type: string
responses:
200:
description: Post deleted.
400:
description: Post cannot be deleted until it is satisfied, withdrawn or expired.
403:
description: The user doesn't have permission to delete the post.
404:
description: Post not found.
/posts/multiple:
get:
tags:
- posts
summary: Retrieve multiple posts
operationId: get_posts_by_ids
produces:
- application/json
parameters:
- name: post_ids
in: query
description: >
A comma separated list of the post IDs.
If more than 10 post IDs are passed, only the first 10 posts will be returned.
required: true
type: string
responses:
200:
description: The posts.
schema:
type: object
properties:
posts:
type: array
items:
$ref: "#/definitions/Post"
not_found:
description: The IDs of posts that weren't found (may have been deleted or never existed).
type: array
items:
type: string
forbidden:
description: The IDs of posts that are forbidden for the current user.
type: array
items:
type: string
security:
- oauth2_implicit:
- basic
- oauth2_code:
- basic
- api_key: []
/posts/{post_id}/reply:
post:
tags:
- posts
summary: Reply to a post
description: Send a reply to a post from the current user to the post author.
operationId: reply_to_post
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: post_id
in: path
description: The ID of the post to reply to.
required: true
type: string
- name: message
in: formData
description: The message to send to the post author.
required: true
type: string
- name: photo_ids
in: formData
description: A comma separated list of the IDs of the photos that should be attached to this reply.
required: false
type: string
responses:
200:
description: The reply has been sent.
400:
description: Missing message parameter or post has been satisfied or withdrawn or expired or the post author is blocked.
403:
description: The user doesn't have permission to reply to the post.
404:
description: Post not found.
/posts/{post_id}/report:
post:
tags:
- posts
summary: Report a post
description: Reports a post to be reviewed by the moderators.
operationId: report_post
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: post_id
in: path
required: true
type: string
- name: reason
in: formData
description: >
The reason that this post is being reported. Must be one of: 'spam',
'not free (for sale/trade/borrow)', 'illegal item', 'not family-friendly',
'other', 'mislabeled: is a Want', 'mislabeled: is an Offer'.
NOTE: If reason is set to 'other', the details parameter is required to be set.
required: true
type: string
- name: details
in: formData
description: >
An explanation from the current user for why they are reporting this post.
This is useful for users to provide evidence or explain why there is a problem with the post.
NOTE: If reason is set to 'other', details are required.
required: false
type: string
responses:
200:
description: The post has been reported.
400:
description: Invalid reason parameter or missing details.
404:
description: Post not found.
#
/posts/{post_id}/bookmark:
put:
tags:
- posts
summary: Bookmark a post
operationId: bookmark_post
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: post_id
in: path
required: true
type: string
responses:
200:
description: The post has been bookmarked.
403:
description: The user doesn't have permission to view the post.
404:
description: Post not found.
delete:
tags:
- posts
summary: Delete a post bookmark
operationId: delete_bookmark
produces:
- application/json
parameters:
- name: post_id
in: path
required: true
type: string
responses:
200:
description: Bookmark deleted.
404:
description: Post not found.
/posts/{post_id}/satisfy:
put:
tags:
- posts
summary: Satisfy a post
description: Mark an offer or wanted post by the current user as satisfied (eg. an offer has been taken or a wanted has been received).
operationId: satisfy_post
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: post_id
in: path
description: The ID of the post to satisfy.
required: true
type: string
responses:
200:
description: The updated post.
schema:
$ref: "#/definitions/Post"
400:
description: Invalid summary or the post is not an offer or wanted post or the post has been withdrawn or has expired.
403:
description: The user doesn't have permission to access the post.
404:
description: Post not found.
/posts/{post_id}/withdraw:
put:
tags:
- posts
summary: Withdraw a post
description: Mark an offer or wanted post by the current user as withdrawn.
operationId: withdraw_post
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: post_id
in: path
description: The ID of the post to withdraw.
required: true
type: string
responses:
200:
description: The updated post.
schema:
$ref: "#/definitions/Post"
400:
description: The post is not an offer or wanted post or the post has already been satisfied or expired.
403:
description: The user doesn't have permission to access the post.
404:
description: Post not found.
/posts/{post_id}/promise:
put:
tags:
- posts
summary: Promise an offer post
description: >
Mark an offer by the current user as promised to someone.
This helps people viewing the post know that the items being offered
may soon be given away as long as the person who was promised the items
picks them up.
operationId: promise_post
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: post_id
in: path
description: The ID of the post to promise.
required: true
type: string
responses:
200:
description: The updated post.
schema:
$ref: "#/definitions/Post"
400:
description: The post is not an offer post or the post has already been satisfied or withdrawn or expired.
403:
description: The user doesn't have permission to access the post.
404:
description: Post not found.
/posts/{post_id}/unpromise:
put:
tags:
- posts
summary: Unpromise an offer post
description: Mark an offer by the current user as unpromised.
operationId: unpromise_post
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: post_id
in: path
description: The ID of the post to unpromise.
required: true
type: string
responses:
200:
description: The updated post.
schema:
$ref: "#/definitions/Post"
400:
description: The post is not an offer post or the post has already been satisfied or withdrawn.
403:
description: The user doesn't have permission to access the post.
404:
description: Post not found.
/posts/{post_id}/share:
post:
tags:
- posts
summary: Share a post
description: Forwards a copy of the post to the current user so that they can forward it to friends.
operationId: share_post
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: post_id
in: path
description: The ID of the post to share.
required: true
type: string
responses:
200:
description: Post shared.
403:
description: The user doesn't have permission to access the post.
404:
description: Post not found.
/photos:
post:
tags:
- photos
summary: Create a photo
operationId: upload_photo
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: photo
in: formData
description: Photo to upload.
required: true
type: file
- name: device_pixel_ratio
in: formData
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
responses:
200:
description: Photo created.
schema:
$ref: "#/definitions/PhotoResult"
400:
description: Invalid photo.
/photos/{photo_id}/rotate:
post:
tags:
- photos
summary: Rotate a photo
operationId: rotate_photo
produces:
- application/json
parameters:
- name: photo_id
in: path
required: true
type: string
- name: degrees
in: query
required: true
type: integer
description: Rotation in degrees - currently only 90, 180 and 270 are supported which correspond to rotate left, rotate upside down and rotate right.
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
responses:
200:
description: Photo rotated.
schema:
$ref: "#/definitions/PhotoResult"
400:
description: Invalid photo.
403:
description: The user doesn't have permission to rotate the photo.
404:
description: Photo not found.
/photos/{photo_id}:
delete:
tags:
- photos
summary: Delete a photo
operationId: delete_photo
produces:
- application/json
parameters:
- name: photo_id
in: path
required: true
type: string
responses:
200:
description: Photo deleted.
400:
description: Invalid photo.
403:
description: The user doesn't have permission to delete the photo.
404:
description: Photo not found.
/photos/multiple:
get:
tags:
- photos
summary: Retrieve multiple photos
operationId: get_photos_by_ids
produces:
- application/json
parameters:
- name: photo_ids
in: query
description: The IDs of the photos to retrieve. If more than 50 photo IDs are passed, only the first 50 photos will be returned.
required: true
type: string
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
responses:
200:
description: The photos.
schema:
type: array
items:
$ref: "#/definitions/PhotoResult"
400:
description: Missing or invalid parameters.
/conversations:
get:
tags:
- messages
summary: List conversations
operationId: get_conversations
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: category
in: query
description: >
Used to filter messases by category. Must be set to one of the following three categories: inbox, archived, blocked
required: false
type: string
default: inbox
- name: page
in: query
description: The page of conversations to return.
required: false
default: 1
minimum: 1
type: integer
- name: per_page
in: query
description: The number of conversations to return per page (must be >= 1 and <= 30).
required: false
default: 10
minimum: 1
maximum: 30
type: integer
- name: num_messages
in: query
description: >
The number of recent messages to return with each conversation.
Additional messages can be retrieved using get conversation messages endpoint.
required: false
type: integer
default: 10
minimum: 0
maximum: 30
- name: include_num_unread
in: query
description: >
If set to 1, the num_unread field in the response will be set to the count of the total number
of conversations that have unread messages.
This is useful for showing users the total number of unread messages that they have in their inbox.
Calculating the count will slow the request down a bit so setting this should be avoided
for requests where it's not needed (eg. requesting archived or blocked conversations or requests
that are just paging through older conversations).
required: false
default: 0
type: integer
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
responses:
200:
description: The conversations and paging data.
schema:
type: object
properties:
conversations:
type: array
items:
$ref: "#/definitions/Conversation"
page:
type: integer
per_page:
type: integer
num_unread:
type: integer
description: >
If the include_num_unread parameter is set to 1, this will be set to the total number of conversations
that have unread messages matching the query parameters of the request. If the include_num_unread
parameter is set to 0, this will be null.
400:
description: Invalid parameters.
/conversations/search:
get:
tags:
- messages
summary: Search conversations
operationId: search_conversations
description: Searches all conversations except blocked conversations.
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: search
in: query
description: The search query used to find conversations and messages.
required: true
type: string
- name: page
in: query
description: The page of conversations to return.
required: false
default: 1
minimum: 1
type: integer
- name: per_page
in: query
description: The number of conversations to return per page (must be >= 1 and <= 30).
required: false
default: 10
minimum: 1
maximum: 30
type: integer
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
responses:
200:
description: The conversations and paging data.
schema:
type: object
properties:
conversations:
type: array
items:
$ref: "#/definitions/Conversation"
page:
type: integer
per_page:
type: integer
search:
type: string
400:
description: Invalid parameters.
/conversations/mark-all-read:
put:
tags:
- messages
summary: Mark all conversations as read
operationId: mark_all_conversations_read
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: message_id
in: formData
description: The message_id of the most recent message from the conversations that the client has downloaded.
required: true
type: string
responses:
200:
description: Conversations marked as read.
400:
description: Invalid message_id.
/conversations/archive-all:
put:
tags:
- messages
summary: Archive all conversations
operationId: archive_all_conversations
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: message_id
in: formData
description: The message_id of the most recent message from the conversations that the client has downloaded.
required: true
type: string
responses:
200:
description: Conversations archived.
400:
description: Invalid message_id.
/conversations/{conversation_id}/block:
put:
tags:
- messages
summary: Block conversation
operationId: block_conversation
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: conversation_id
in: path
description: The ID of the conversation to block.
required: true
type: string
responses:
200:
description: Conversation blocked.
400:
description: Conversations with moderators cannot be blocked.
403:
description: The user doesn't have permission to modify this conversation.
404:
description: Conversation not found.
/conversations/{conversation_id}/unblock:
put:
tags:
- messages
summary: Unblock conversation
operationId: unblock_conversation
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: conversation_id
in: path
description: The ID of the conversation to unblock.
required: true
type: string
responses:
200:
description: Conversation unblocked.
403:
description: The user doesn't have permission to modify this conversation.
404:
description: Conversation not found.
/conversations/{conversation_id}/archive:
put:
tags:
- messages
summary: Archive conversation
operationId: archive_conversation
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: conversation_id
in: path
description: The ID of the conversation to archive.
required: true
type: string
responses:
200:
description: Conversation archived.
403:
description: The user doesn't have permission to modify this conversation.
404:
description: Conversation not found.
/conversations/{conversation_id}/unarchive:
put:
tags:
- messages
summary: Unarchive conversation
operationId: unarchive_conversation
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: conversation_id
in: path
description: The ID of the conversation to unarchive.
required: true
type: string
responses:
200:
description: Conversation unarchived.
403:
description: The user doesn't have permission to modify this conversation.
404:
description: Conversation not found.
#
/conversations/{conversation_id}/mark-read:
put:
tags:
- messages
summary: Mark conversation as read
operationId: mark_conversation_read
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: conversation_id
in: path
description: The ID of the conversation to mark as read.
required: true
type: string
- name: message_id
in: formData
description: The ID of the newest message in the conversation that the current user has read.
required: true
type: string
responses:
200:
description: Conversation marked as read.
400:
description: Invalid parameters.
403:
description: The user doesn't have permission to modify this conversation.
404:
description: Conversation or message not found.
/conversations/{conversation_id}/reply:
post:
tags:
- messages
summary: Reply to conversation
operationId: reply_to_conversation
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: conversation_id
in: path
description: The ID of the conversation to reply to.
required: true
type: string
- name: content
in: formData
description: The content of the reply.
required: true
type: string
- name: photo_ids
in: formData
description: A comma separated list of the IDs of the photos that should be attached to this message.
required: false
type: string
- name: device_pixel_ratio
in: formData
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
responses:
200:
description: The new message sent to the conversation.
schema:
$ref: "#/definitions/Message"
400:
description: Invalid parameters or duplicate reply or conversation is blocked.
403:
description: The user doesn't have permission to reply to the conversation.
404:
description: Conversation not found.
/conversations/{conversation_id}/messages:
get:
tags:
- messages
summary: List conversation messages
operationId: get_conversation_messages
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: conversation_id
in: path
description: The ID of the conversation to return messages from.
required: true
type: string
- name: page
in: query
description: The page of messages to return.
required: false
default: 1
minimum: 1
type: integer
- name: per_page
in: query
description: The number of messages to return per page (must be >= 1 and <= 30).
required: false
default: 10
minimum: 1
maximum: 30
type: integer
- name: device_pixel_ratio
in: query
description: Client device pixel ratio used to determine thumbnail size (default 1.0).
required: false
default: 1.0
type: number
- name: include_conversation
in: query
description: If set to 1, the conversation will be returned along with the messages.
required: false
type: integer
default: 0
responses:
200:
description: >
The messages and page data. The conversation data is optional and is only returned
if the include_conversation parameter is set.
schema:
type: object
properties:
messages:
type: array
items:
$ref: "#/definitions/Message"
page:
type: integer
per_page:
type: integer
conversation:
$ref: "#/definitions/Conversation"
400:
description: Invalid parameters.
403:
description: The user doesn't have permission to access the conversation.
404:
description: Conversation not found.
/conversations/{conversation_id}/report:
post:
tags:
- messages
summary: Report conversation
operationId: report_conversation
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: conversation_id
in: path
description: The ID of the conversation to report.
required: true
type: string
- name: reason
in: formData
description: A user provided reason why the conversation is being reported.
required: true
type: string
responses:
200:
description: Conversation reported.
400:
description: Empty reason parameter.
403:
description: The user doesn't have permission to report the conversation.
404:
description: Conversation not found.
/conversations/{conversation_id}:
delete:
tags:
- messages
summary: Delete conversation
operationId: delete_conversation
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: conversation_id
in: path
description: The ID of the conversation to delete.
required: true
type: string
- name: message_id
in: query
description: The ID of the newest message in the conversation that the client has downloaded.
required: true
type: string
#
responses:
200:
description: Conversation deleted.
400:
description: Invalid parameters.
403:
description: The user doesn't have permission to modify this conversation.
404:
description: Conversation or message not found.
securityDefinitions:
oauth2_implicit:
type: oauth2
authorizationUrl: https://trashnothing.com/oauth2/authorize
flow: implicit
scopes:
basic: Provides full access to a user's account
description: >
This is the default OAuth2 flow for new apps.
oauth2_code:
type: oauth2
authorizationUrl: https://trashnothing.com/oauth2/authorize
tokenUrl: https://trashnothing.com/oauth2/token
flow: accessCode
scopes:
basic: Provides full access to a user's account
description: >
This OAuth2 flow is designed for server side apps and is not enabled by default for new apps.
If you would like to use this flow for your app, contact us through the
[trash nothing Developer page](https://trashnothing.com/developer).
api_key:
type: apiKey
name: api_key
in: query
description: >
Provides access to specific public API endpoints which don't require user authorization.
The API currently allows api key access to list, search and retrieve posts (for public posts and posts on open archive groups)
and to list, search and retrieve groups.
NOTE: Some API endpoints behave differently when requests are made using api keys instead of oauth (because api key requests
have no user associated with them). Check the documentation for each endpoint for a description of the differences.
definitions:
GeolocateBounds:
description: >
Two bounding boxes that make using Google Maps' geocoder easier.
The default bounding box defines the area in which the post is probably located.
This is useful for providing a bounds to Google Maps geocoder.
The limit bounding box is a larger bounding box that contains the default bounding box.
This is useful for discarding Google Maps geocoding results that are outside of this bounding box.
type: object
properties:
default:
$ref: "#/definitions/BoundingBox"
limit:
$ref: "#/definitions/BoundingBox"
BoundingBox:
description: A geographic bounding box defined by its southwest and northeast points.
type: object
properties:
southwest:
type: object
description: The point defining the southwest corner of the bounding box.
properties:
latitude:
type: number
longitude:
type: number
northeast:
type: object
description: The point defining the northeast corner of the bounding box.
properties:
latitude:
type: number
longitude:
type: number
example:
southwest:
latitude: 51.0025285305
longitude: -3.5323240284
northeast:
latitude: 52.8293255665
longitude: -0.600956182
PhotoResult:
description: The result of uploading or editing a photo.
type: object
properties:
photo_id:
type: string
thumbnail:
type: object
description: Photo thumbnail data.
properties:
url:
type: string
width:
type: integer
height:
type: integer
example:
photo_id: 987-423
thumbnail:
url: https://trashnothing.com/img/2018-02-02/307731-20180119_155358.90x120.jpg
width: 90
height: 120
PostSearchResult:
allOf:
- $ref: "#/definitions/Post"
- type: object
properties:
search_title:
type: string
description: >
The post subject as HTML with the parts of the subject that matched the search
query (if any) wrapped in HTML span tags with the class 'highlight'.
(eg. <span class="highlight">matched words</span>). May be null if
none of the words in the subject matched the search query.
search_content:
type: string
description: >
A snippet of the post content as HTML with the parts of the content that matched the search
query (if any) wrapped in an HTML span tags with the class 'highlight' (eg. <span class="highlight">matched words</span>).
May be null if none of the words in the post content matched the search query.
NOTE: This is not the full content of the post It is just a snippet of around 200 characters that can be
used to display the parts of the post content relevant to the search query.
example:
post_id: 25997431
group_id: 81
user_id: 82928
title: Microwave Oven (Greenfield)
content: >
Panasonic microwave oven in good working order
800 W power and turntable inside
Has all the normal microwave functions plus grill elements for browning
Comes with original instructions booklet
It's an old microwave and could do with a bit of a clean, but still works very well
date: "2018-02-18T17:11:38"
type: offer
outcome: null
latitude: 42.961404
longitude: -88.012586
footer: null
photos: null
expiration: "2018-04-18T17:11:38"
reselling: false
url: https://trashnothing.com/post/25997431/microwave-oven-greenfield
repost_count: 0
search_title: Microwave Oven (Greenfield)
search_content: Panasonic microwave oven in good working order 800 W power and turntable
Photo:
type: object
properties:
photo_id:
type: string
thumbnail:
type: string
description: A URL to a thumbnail of this photo. The size of the thumbnail depends on the device_pixel_ratio parameter and it is not guaranteed to be square.
url:
type: string
description: A URL to a large version of this photo (but not necessarily the largest size available).
blurhash:
type: string
description: >
A blurhash of the photo that can be used as a placeholder while the photo is loading (see: https://github.com/woltapp/blurhash).
May be null if no blurhash is available and the length of the blurhash can vary based on the photo.
images:
type: array
description: All the versions of this photo ordered from smallest to largest. This list is guaranteed to include the photos specified by the above thumbnail and url properties.
items:
type: object
properties:
url:
type: string
width:
type: integer
height:
type: integer
example:
photo_id: 695624-768616
thumbnail: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.90x120.jpg
url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.375x500.jpg
blurhash: 'TkJ7jsoz%f~VoLxu-pWCWB-oj[M|'
images:
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.90x120.jpg
width: 90
height: 120
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.180x240.jpg
width: 180
height: 240
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.270x360.jpg
width: 270
height: 360
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.375x500.jpg
width: 375
height: 500
Post:
description: An offer, wanted, admin, taken or received post.
type: object
properties:
post_id:
type: string
source:
type: string
description: >
The source of the post. One of: groups, trashnothing, open_archive_groups. A value of groups
or open_archive_groups indicates the post is from a group and the group_id field will contain the ID of the group.
A value of trashnothing indicates the post is a public post not associated with any group.
group_id:
type: string
description: >
The group ID of the post. For public posts, this is always null.
user_id:
type: string
title:
type: string
content:
type: string
date:
type: string
format: date-time
description: The UTC date and time when the post was published.
type:
type: string
description: >
The type of post. One of: offer, taken, wanted, received, admin
outcome:
type: string
description: >
For offer and wanted posts, this indicates the outcome of the post which is null
if no outcome has been set yet.
Offer post outcomes will be one of: satisfied, withdrawn, promised, expired
Wanted post outcomes will be one of: satisfied, withdrawn, expired
For all other posts, outcome is always null.
latitude:
type: number
description: May be null if a post hasn't been mapped.
longitude:
type: number
description: May be null if a post hasn't been mapped.
footer:
type: string
description: Some groups add footers to posts that are separate and sometimes unrelated to the post itself - such as reminders about group rules or features (may be null).
photos:
type: array
description: Details about the photos associated with this post (may be null if there are no photos).
items:
$ref: "#/definitions/Photo"
expiration:
type: string
format: date-time
description: >
The UTC date and time when the post will expire.
Currently only offer and wanted posts expire. For all other posts, expiration is always null.
reselling:
type: boolean
description: >
For wanted posts, whether the item is being requested in order to resell it or not.
Will be null for all posts that are not wanted posts and for wanted posts where the poster hasn't
indicated whether or not they intend to resell the item they are requesting.
url:
type: string
description: The link to use to view the post on the trash nothing site.
repost_count:
type: integer
description: >
The count of how many times this post has been reposted in the last 90 days.
A value of zero is used to indicate that the post is not a repost.
The count is specific to the source of the post (eg. the specific group the post is on).
If a post is crossposted to multiple groups, the repost_count of the post on each group may
be different for each group depending on how many times the post has been posted on that group
in the last 90 days.
example:
post_id: 3171898
group_id: 6
user_id: 2933
title: Ultrasonic diffuser (Downtown Toronto)
content: This ultrasonic diffuser creates an aroma in your home. It comes with two essential oils - mint and lavender.
date: "2018-02-05T15:10:21"
type: offer
outcome: satisfied
latitude: 43.653226
longitude: -79.383184
footer: null
photos:
- photo_id: 695624-768616
thumbnail: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.90x120.jpg
url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.375x500.jpg
images:
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.90x120.jpg
width: 90
height: 120
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.180x240.jpg
width: 180
height: 240
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.270x360.jpg
width: 270
height: 360
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.375x500.jpg
width: 375
height: 500
expiration: "2018-03-05T15:10:21"
reselling: false
url: https://trashnothing.com/post/3171898/ultrasonic-diffuser-downtown-torronto
repost_count: 1
Conversation:
description: A conversation between the current user and another user.
type: object
properties:
conversation_id:
type: string
user:
description: >
The user that the conversation is with (this is not the current user).
This may be set to null if the user this conversation was with removed their account.
$ref: "#/definitions/User"
last_message_date:
type: string
format: date-time
description: The UTC date and time of the last message in this conversation.
num_unread_messages:
type: integer
description: The count of how many unread messages this conversation has.
blocked:
type: boolean
description: Whether or not this conversation is blocked.
archived:
type: boolean
description: Whether or not this conversation is archived.
messages:
type: array
description: The latest messages in this conversation.
items:
$ref: "#/definitions/Message"
example:
conversation_id: 38914
user:
user_id: 2946512
username: fred gibson
country: GB
profile_image: https://lh3.googleusercontent.com/-1qVLzuOCyYg/AAAAAAAAAAI/AAAAAAAAAAA/0aGNzRAO61c/s64-c/100783935580725962164.jpg
member_since: "2017-01-27T06:35:55"
firstname: null
lastname: null
about_me: Just an old fisherman looking to reuse more.
last_message_date: "2019-07-24T22:51:09"
num_unread_messages: 1
blocked: false
archived: false
messages:
- message_id: 10199633
from_user_id: 2946512
to_user_id: 119458
date: "2019-07-24T22:29:10"
subject: Dining Table and 4 Chairs
content: Here are some photos and the directions for pick up.
email_attachments:
- Directions and map.pdf
photos:
- photo_id: 695624-768616
thumbnail: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.90x120.jpg
url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.375x500.jpg
images:
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.90x120.jpg
width: 90
height: 120
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.180x240.jpg
width: 180
height: 240
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.270x360.jpg
width: 270
height: 360
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.375x500.jpg
width: 375
height: 500
Message:
description: A message between two users.
type: object
properties:
message_id:
type: string
from_user_id:
type: string
description: The ID of the user that sent the message (the sender).
to_user_id:
type: string
description: The ID of the user that received the message (the recipient).
date:
type: string
format: date-time
description: The UTC date and time when the message was sent.
subject:
type: string
description: >
Because many messages are received by email, all messages have a subject.
The subject is often useful to allow the recipient to determine which post
a message may be referring to. In rare cases, some senders send emails with
a subject and but no email body which causes the message content to be an
empty string.
content:
type: string
description: The content of the message.
#
email_attachments:
type: array
description: >
Every message a user receives is made available via the API and is sent to the
user by email. Some messages may contain unsupported attachments that are not
available by the API but are emailed to the user (eg. documents, videos, zip files).
The email_attachments field provides the names of all the unsupported attachments that
were emailed to the user (will be null if there are no unsupported attachments).
items:
type: string
photos:
type: array
description: Details about the photos associated with this message (may be null if there are no photos).
items:
$ref: "#/definitions/Photo"
post:
$ref: "#/definitions/Post"
description: The post referenced by this message. May be null if the message couldn't be matched to any post.
example:
message_id: 10199633
from_user_id: 2946512
to_user_id: 119458
date: "2019-07-24T22:29:10"
subject: Dining Table and 4 Chairs
content: Here are some photos and the directions for pick up.
email_attachments:
- Directions and map.pdf
photos:
- photo_id: 695624-768616
thumbnail: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.90x120.jpg
url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.375x500.jpg
images:
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.90x120.jpg
width: 90
height: 120
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.180x240.jpg
width: 180
height: 240
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.270x360.jpg
width: 270
height: 360
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.375x500.jpg
width: 375
height: 500
post: null
Story:
description: A user story
type: object
properties:
story_id:
type: string
title:
type: string
content:
type: string
date:
type: string
format: date-time
description: The UTC date and time when the post was published.
user:
description: The user that submitted the story.
$ref: "#/definitions/User"
like_count:
type: integer
description: The number of people who have liked this story.
user_liked:
type: boolean
description: Whether or not the current user has liked this story or not.
share_url:
type: string
description: A URL that can be used to share the story (may be null if the story is not public).
photos:
type: array
description: Details about the photos associated with this story (may be null if there are no photos).
items:
$ref: "#/definitions/Photo"
example:
story_id: 7584
title: Sharing is caring
content: People helping people - it doesn't get better than this!
date: "2020-04-25T10:26:32"
user:
user_id: 2946512
username: fred gibson
country: GB
profile_image: https://lh3.googleusercontent.com/-1qVLzuOCyYg/AAAAAAAAAAI/AAAAAAAAAAA/0aGNzRAO61c/s64-c/100783935580725962164.jpg
member_since: "2017-01-27T06:35:55"
firstname: null
lastname: null
about_me: Just an old fisherman looking to reuse more.
like_count: 3
share_url: https://trashnothing.com/story/7584
photos:
- photo_id: 695624-768616
thumbnail: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.90x120.jpg
url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.375x500.jpg
images:
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.90x120.jpg
width: 90
height: 120
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.180x240.jpg
width: 180
height: 240
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.270x360.jpg
width: 270
height: 360
- url: https://trashnothing.com/img/2018-02-05/cfsbfm-39051735845_379baab73f.375x500.jpg
width: 375
height: 500
Alert:
description: A search alert that the user has created so that they can be notified when new posts match the search query specified by the alert.
type: object
properties:
alert_id:
type: string
user_id:
type: string
search:
type: string
description: The search phrase that the alert triggers on.
types:
type: array
description: >
A list of the post types that the alert is set to match against. The available post types are: offer, wanted
NOTE: Additional post types may be added in the future (eg. events) so clients should take care to support arbitrary
types being returned.
items:
type: string
send_count:
type: integer
description: The number of time the alert has triggered and been send out.
last_sent:
type: string
format: date-time
description: The UTC date and time when the alert was last triggered and sent out (may be null).
example:
alert_id: 7584
user_id: 9191
search: table
types:
- offer
send_count: 3
last_sent: "2018-02-16T12:58:51"
# TODO: client needs to implement support for group notices for TN groups..
GroupNotice:
description: Group notices are created by group moderators in order to provide useful information to the group members (eg. group rules and guidelines).
type: object
properties:
notice_id:
type: string
group_id:
type: string
date:
type: string
format: date-time
description: The UTC date and time when this notice was received.
title:
type: string
content:
type: string
example:
notice_id: 81178
group_id: 1781
date: "2018-02-17T13:22:40"
title: Group Rules & Guidelines
content: Everything must be free, legal and appropriate for all ages. Repeat offenders will be banned.
Group:
description: >
Groups are run by volunteer moderators and provide a way to group activity in a specific location.
Because each group is usually run by different people, there can be variations in rules from group
to group (eg. who is allowed to join, what is allowed to be posted, how often reposts are allowed).
type: object
properties:
group_id:
type: string
name:
type: string
description: The name of the group (not guaranteed to be unique).
identifier:
type: string
description: A unique identifier for the group that is used in URLs.
homepage:
type: string
description: A URL to the group homepage.
member_count:
type: integer
description: The number of members who belong to the group.
latitude:
type: number
longitude:
type: number
timezone:
type: string
description: The timezone that the group is in (eg. America/New_York).
#
open_membership:
type: boolean
description: When true, the group allows anyone to join. When false, the group moderators review and approve applicants.
open_archives:
type: boolean
description: When true, the group posts are viewable by anyone. When false, the group posts can only be viewed by members of the group.
has_questions:
type: boolean
description: When true, anyone requesting membership to this group will be required to answer a new membership questionnaire.
country:
type: object
description: Provides information about the country that is associated with a group. May be null.
properties:
name:
type: string
description: The name of the country.
abbreviation:
type: string
description: >
A 2 letter country code for the country (see https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 ).
example:
name: United States
abbreviation: US
region:
type: object
description: Provides information about an area within a country that a group is associated with (eg. a state in the US or a province in Canada). May be null.
properties:
name:
type: string
description: The name of the region.
abbreviation:
type: string
description: A 2 letter abbreviation for the region (is not guaranteed to be globally unique but is unique among all the regions in the country).
example:
name: California
abbreviation: CA
membership:
type: object
description: >
Provides information about the current users' active or pending membership to this group (if any).
Will be null if there is no active or pending membership to this group.
properties:
status:
type: string
description: >
One of: subscribed, pending, pending-questions
date:
type: string
format: date-time
description: >
The UTC date and time when the membership was last updated.
questionnaire:
type: object
description: Membership questionnaire data. Will be null unless the membership status is pending-questions.
properties:
message:
type: string
description: A message from the group moderators to be displayed above the questions (may be null).
questions:
type: array
description: The list of questions.
items:
type: string
example:
group_id: 46
name: Ottawa Reuse
identifier: OttawaReuse
homepage: https://trashnothing.com/OttawaReuse
member_count: 4838
latitude: 45.423494
longitude: -75.697933
timezone: America/Toronto
open_membership: false
open_archives: false
has_questions: true
country:
name: Canada
abbreviation: CA
region:
name: Ontario
abbreviation: ON
membership:
status: pending-questions
date: "2015-01-22T17:05:50"
questionnaire:
message: This group is only for people who live in Ottawa.
questions:
- Where do you live?
Feedback:
type: object
properties:
feedback_id:
type: string
user_id:
type: string
description: The user ID of the user that the feedback is about.
reviewer_user_id:
type: string
description: The user ID of the user that submitted the feedback.
content:
type: string
description: A comment written by the reviewer about the user (may be null).
positive:
type: boolean
description: Set to true for positive feedback and false for negative feedback.
date:
type: string
format: date-time
description: Date when the feedback was submitted.
example:
user_id: 2946512
reviewer_user_id: 9191
content: Fred gave me a great antique table for my new apartment!
positive: true
date: "2020-03-01T12:01:22"
User:
type: object
properties:
user_id:
type: string
username:
type: string
description: >
A username that can be displayed for the user (the username is NOT guaranteed to be unique).
Will be null for api key requests and requests where the oauth user doesn't belong to any of the same groups
as this user.
country:
type: string
description: >
A 2 letter country code for the country that has been automatically detected for the user (see https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 ). May be null if no country has been set.
profile_image:
type: string
description: >
A URL to a profile image for the user. Profile images sizes vary based on the source (Google, Facebook, Gravatar, etc)
and some can be as small as 64px by 64px. Will be null for api key requests and requests where the oauth user doesn't belong
to any of the same groups as this user.
member_since:
type: string
description: The date and time when the user first became publicly active on a group (the date may be older than when the user signed up).
firstname:
type: string
description: The first name of the user (may be null).
lastname:
type: string
description: The last name of the user (may be null).
reply_time:
type: integer
description: >
An estimate of how many seconds it takes this user to reply to messages.
May be null when there is not enough data to calculate an estimate.
feedback:
type: object
properties:
restriction:
type: string
description: >
If the current user can leave positive or negative feedback on this user then restriction is null.
Otherwise, restriction is set to a string that explains why feedback is currently restricted and
what type of feedback is restricted. The string will be one of the following:
no-recent-messages, negative-score, moderator, [days]-day-wait-for-negative
- **no-recent-messages**: The current user has not received any messages from this user in the last 30 days.
- **negative-score**: The current user has a negative feedback and will not be able to leave feedback until their score is >= 0.
- **moderator**: The user is a moderator and leaving feedback on moderators is not currently supported.
- **[days]-day-wait-for-negative**: Positive feedback is not restricted but the current user must wait
some number of days before they will be able to leave negative feedback on this user. This string can
change depending on the number of days. For example, when the current user must wait one day, the
string will be '1-day-wait-for-negative'. A wait is necessary because a lot of negative feedback results
from communication issues that are resolved with more time.
score:
type: integer
description: >
The feedback score of this user. Higher scores are better.
Scores are calculated by substracting the total number of negative feedback from the total number of positive feedback
that a user has received. May be null if a user has not received enough feedback to calculate a score.
percent_positive:
type: number
description: >
The percent of feedback that this user has received in the last year that was positive.
May be null if a user has not received enough feedback to calculate a percentage.
minimum: 0
maximum: 100
about_me:
type: string
description: >
A short bio a user has written about themselves to help other members get to know them better.
May be null if the user has not written anything about themselves.
example:
user_id: 2946512
username: fred gibson
country: GB
profile_image: https://lh3.googleusercontent.com/-1qVLzuOCyYg/AAAAAAAAAAI/AAAAAAAAAAA/0aGNzRAO61c/s64-c/100783935580725962164.jpg
member_since: "2017-01-27T06:35:55"
firstname: null
lastname: null
reply_time: 4850
feedback:
restriction: no-recent-messages
score: 7
percent_positive: 87.5
about_me: Just an old fisherman looking to reuse more.
CurrentUser:
allOf:
- $ref: "#/definitions/User"
- type: object
properties:
public_name:
type: boolean
description: Whether or not the user has chosen to make their first and last name public.
verified:
type: boolean
description: >
Whether or not the user has verified their account.
The user account will be limited (eg. they will not be able to reply to posts) until their account is verified.
has_password:
type: boolean
description: >
Whether or not the user has a password (accounts created using 3rd party providers like Facebook don't have passwords set).
When has_password is false, the only way to set a password on the users' account is to send the user a password reset email.
email:
type: object
description: Data related to the users' email address.
properties:
address:
type: string
description: The email address.
bouncing:
type: boolean
description: >
Whether or not this email address has been bouncing emails that are sent to it. When bouncing is true,
no emails will be sent to the user. If the user thinks that their email account shouldn't be bouncing
emails, use the email not bouncing endpoint to reset bouncing to false.
spam_stop:
type: boolean
description: >
Whether or not emails have been stopped because of a spam complaint from the users' email account.
When spam_stop is first set to true, it indicates that all emails have been automatically disabled
for the users' account (eg. digest and alerts). The user will need to re-enable digests and re-add
any alerts that they had previously set up.
uses_fair_offer_policy:
type: boolean
description: Whether or not the user used the Fair Offer Policy (see https://trashnothing.com/fair_offer_policy ) the last time they posted.
email_posts_frequency:
type: string
description: >
How often new post email notifications are sent to the user.
One of: weekly, twice_weekly, daily, 12_hours, 8_hours, 6_hours, 4_hours, 2_hours, hourly
Will be null if new post email notifications are turned off.
digest_photos:
type: boolean
description: Whether or not photos are included in the digest emails sent to the user.
email_post_reminders:
type: boolean
description: Whether or not post reminder emails are enabled for this user (to remind them to update or repost their posts).
email_search_alerts:
type: boolean
description: Whether or not search alert emails are enabled for this user.
email_message_delay:
type: string
description: >
How quickly new messages from other users are emailed to this user.
One of: immediate, 30_minutes, 1_hour, 2_hours, 4_hours, 6_hours, 8_hours
If set to anything other than immediate, the user will receive a digest email
summarizing all of the new messages that they haven't viewed.
special_notices:
type: boolean
description: >
Whether or not the user wants to receive special notice emails from the groups they are a member of.
Special notices are admin posts that the group moderators choose to send out by email.
signup:
type: string
format: date-time
description: The UTC date and time when the user signed up.
profile_image_source:
type: string
description: >
The source of the users' profile image. One of: gravatar, facebook, google, freegle, custom
last_listings_view:
type: string
format: date-time
description: >
The UTC date and time when the user last viewed the newest posts on the All Posts page (may be null).
NOTE: For this to be accurate, clients must update the last_listings_view property of the current user every time the user is shown
the newest posts on the All Posts page.
location:
type: object
description: The users' location. The location is used to determine which posts are shown to the user (may be null).
properties:
name:
type: string
description: A text description of the location specified by latitude and longitude.
latitude:
type: number
longitude:
type: number
radius:
type: number
description: Defines the radius (in meters) of a circle around the point specified by latitude and longitude.
minimum: 0
maximum: 257500
public_post_sources:
type: array
description: >
A list of the public post sources the user is interested in seeing posts from (currently only 'trashnothing' is supported).
If the array is empty, no sources are enabled and the user will only see posts from the groups they are a member of.
NOTE: Additional sources may be added in the future so clients should take care to support arbitrary sources being returned.
items:
type: string
show_all_group_posts:
type: boolean
description: >
If true, all group posts from the users' groups are shown to them on the main posts page and in the digests.
If false, only group posts in the area defined by the users' location are shown.
example:
user_id: 119458
username: captainjack
country: US
profile_image: https://gravatar.com/avatar/88305a95b05b30f6cd306019ea5d88f3?s=90&r=pg&default=identicon
member_since: "2009-09-25T14:20:01"
firstname: Jack
lastname: Carter
about_me: I used to be an accountant but then I decided to become a pirate.
public_name: false
verified: true
has_password: false
email:
address: johndoe@example.com
verified: true
bouncing: false
spam_stop: false
uses_fair_offer_policy: true
email_posts_frequency: 6_hours
digest_photos: false
show_all_group_posts: true
email_post_reminders: true
email_search_alerts: true
email_message_delay: immediate
special_notices: true
signup: "2017-11-20T04:32:06"
profile_image_source: gravatar
last_listings_view: "2018-02-15T15:04:47"
location:
name: Wheat Ridge, CO, USA
latitude: 39.766098
longitude: -105.077206
radius': 32186.88
public_post_sources: #
- trashnothing
#