Organization Admin
The org-scoped admin panel at /org-admin/{slug}/*. Every operation needs a bearer session, resolves {slug} to an organization (an unknown or malformed slug answers 404 Organization not found, never 403), and then checks an org-scoped permission held through the caller's org_owner, org_admin or org_viewer role on that organization. A caller without the permission gets 403 with message: "Requires permission: <name>".
Role → permission map: org_viewer holds org.read, org.read_donations, org.read_payouts and org.read_donors. org_admin adds org.update_settings, org.manage_members, org.manage_dbas, org.manage_locations and org.upload_documents. org_owner adds org.manage_children and org.manage_payouts.
Get organization dashboard totals
Headline numbers for the org-admin dashboard. For a conglomerate the figures roll up the organization and all of its child organizations; for a company they cover the organization alone. totalRaisedCents sums every paid donation on those organizations' fundraisers, in integer cents. uniqueDonors counts distinct signed-in donors only — guest donations do not add to it.
Requires permission: org.read
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Responses
Dashboard totals
List the organization's fundraisers
Non-deleted fundraisers owned by this organization (not its children), newest first, with offset pagination. Every status is included — drafts, pending review, ended — unless status narrows it. Private contact fields are never returned.
Requires permission: org.read
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Query Parameters
Only fundraisers with this status. Send one of the listed values.
"draft""pending""rejected""active""paused""ended"Clamped to 1..100. Defaults to 20.
11002000Responses
Paginated fundraisers
List donations to the organization's fundraisers
Donations to this organization's non-deleted fundraisers, newest first, with offset pagination. Every payment status is returned unless status narrows it.
Donor privacy: donor_display_name is Anonymous donor when the gift was marked anonymous, the donor's profile name for a signed-in donor, and the checkout name for a guest. Donor email addresses are never returned.
Requires permission: org.read_donations
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Query Parameters
Only donations with this payment status. Send one of the listed values.
"paid""pending""failed""refunded"Only donations to this fundraiser. Must be a UUID.
"uuid"Clamped to 1..100. Defaults to 20.
11002000Responses
Paginated donations
List the organization's donors
Distinct donors who made a paid donation to any of this organization's non-deleted fundraisers, with their lifetime totals here, largest first, with offset pagination. All anonymous gifts are collapsed into a single Anonymous donor row (donor_key: anonymous) so they cannot be told apart by amount. Signed-in donors are keyed user:<profile id>; guest donors are keyed guest:<24 hex characters>. Treat donor_key as an opaque identifier: it is stable across pages and requests, but carries no contact details and cannot be turned back into one.
Requires permission: org.read_donors
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Query Parameters
Clamped to 1..100. Defaults to 20.
11002000Responses
Paginated donor roll-up
Look up an account by email before adding it as a member
Confirms which FundlyHub account uses an email address, for the Members page's "Add member" form. q must be a complete email address; it is matched case-insensitively against account login emails only, and at most one result comes back, with the address masked. Anything that is not a complete email address (a name, a fragment, a phone number) answers 200 with an empty list. This is not a directory search.
Available only to organizations that are approved or verified; any other organization gets 403 with code: ORG_NOT_APPROVED.
Rate limited to 30 requests per minute per user, in one bucket shared with POST /org-admin/{slug}/members.
Note the bare { "results": [ … ] } envelope rather than data.
Requires permission: org.manage_members
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Query Parameters
A complete email address (surrounding whitespace is trimmed). Matched case-insensitively against account login emails.
"sam@example.org""email"254Responses
The matching account, or an empty list when no account uses that email or q is not a complete email address.
List organization members
Everyone holding an active, unexpired org-scoped role on this organization, highest role first, then by name. Includes each member's email address, which is why this sits behind the management permission rather than org.read.
Requires permission: org.manage_members
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Responses
Members
Add a member
Adds an existing FundlyHub user, found by email (case-insensitive), to the organization with the given role. The membership is active immediately; no invitation is sent and the user does not have to accept. org_owner cannot be granted here — add the user first, then promote them with PATCH /org-admin/{slug}/members/{userId}.
An optional display title can be set with either org_role_title_id (an id from GET /org-role-titles) or custom_role_title, not both.
Available only to organizations that are approved or verified; any other organization gets 403 with code: ORG_NOT_APPROVED.
Rate limited to 30 requests per minute per user, in one bucket shared with GET /org-admin/{slug}/users/search.
Requires permission: org.manage_members
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Request Body
Responses
Member added
Remove a member
Deactivates every org-scoped role the user holds on this organization. Only an org_owner may remove an owner, and nobody may remove a member whose role is equal to or above their own (403). Removing yourself (leaving) is always allowed. The organization's last remaining owner cannot be removed (400) — promote another member to owner first.
Requires permission: org.manage_members
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"The member's profile id. A non-UUID answers 404 Member not found.
"uuid"Responses
Member removed
Change a member's role
Moves a member to a different org role. Setting the role they already hold is an idempotent no-op that still answers 200.
Roles rank org_owner > org_admin > org_viewer. Rules enforced, each a 403 when broken:
- only an
org_ownermay promote anyone toorg_owner, or change the role of another owner; - nobody may change the role of a member whose role is equal to or above their own (an
org_adminmanagesorg_viewers, not other admins); - nobody may grant a role above their own.
Lowering your own role (stepping down) is always allowed. The organization's last remaining owner cannot be demoted (400) — promote another member to owner first.
Requires permission: org.manage_members
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"The member's profile id. A non-UUID answers 404 Member not found.
"uuid"Request Body
Responses
Role updated (or already held)
Update organization settings
Partial update of the organization's profile. Only the fields below are writable; others are ignored. String fields accept a string or null and are trimmed. At least one writable field must be present.
logo and banner_image take a URL as-is; to upload an image use POST /org-admin/{slug}/avatar or /banner instead.
Requires permission: org.update_settings
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Request Body
Responses
Updated settings
Upload organization logo
Uploads a new logo as base64 JSON. The image is centre-cropped to 256×256, re-encoded as WebP, stored, and written to the organization's logo straight away — no separate settings save is needed. Any previous logo file is deleted. Maximum 5 MB decoded.
Note the bare response body (no data envelope).
Requires permission: org.update_settings
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Request Body
Responses
Logo uploaded
Remove organization logo
Deletes the stored logo files and clears the organization's logo.
Requires permission: org.update_settings
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Responses
Logo removed
Post an organization update
Publishes a post to the organization's public updates feed (GET /organizations/{id}/updates). The caller is recorded as the author.
Requires permission: org.update_settings
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Request Body
Responses
Update posted
Delete an organization update
Permanently deletes one of this organization's updates. A malformed updateId answers 500 rather than 404.
Requires permission: org.update_settings
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$""uuid"Responses
Update deleted
Edit an organization update
Partial edit of one of this organization's updates. Send at least one of title, body, cover_image.
Requires permission: org.update_settings
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$""uuid"Request Body
Responses
Update edited
Upload organization banner
Uploads the public-profile banner as base64 JSON. The image is centre-cropped to 1500×500 (3:1), re-encoded as WebP, stored, and written to the organization's banner_image straight away. Any previous banner file is deleted. Maximum 8 MB decoded.
Note the bare response body (no data envelope).
Requires permission: org.update_settings
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Request Body
Responses
Banner uploaded
Remove organization banner
Deletes the stored banner files and clears the organization's banner_image.
Requires permission: org.update_settings
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Responses
Banner removed
List DBAs
The organization's "doing business as" names, default first, then alphabetical.
Requires permission: org.read
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Responses
DBAs
Add a DBA
Adds a DBA name. With is_default: true it becomes the default and the previous default is cleared in the same transaction.
Requires permission: org.manage_dbas
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Request Body
Responses
DBA added
Delete a DBA
Permanently deletes a DBA. Deleting the default leaves the organization with no default DBA.
Requires permission: org.manage_dbas
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"A non-UUID answers 404 DBA not found.
"uuid"Responses
DBA deleted
Update a DBA
Renames a DBA and/or changes whether it is the default. Setting is_default: true clears the previous default in the same transaction.
Requires permission: org.manage_dbas
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"A non-UUID answers 404 DBA not found.
"uuid"Request Body
Responses
DBA updated
List office locations
The organization's physical locations, primary first, then oldest first. Includes locations not shown publicly.
Requires permission: org.read
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Responses
Locations
Add an office location
Adds a location. With is_primary: true it becomes the primary location and the previous primary is cleared in the same transaction. Locations are hidden from the public profile unless is_publicly_visible is true.
Requires permission: org.manage_locations
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Request Body
Responses
Location added
Delete an office location
Permanently deletes a location. Deleting the primary leaves the organization with no primary location.
Requires permission: org.manage_locations
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"A non-UUID answers 404 Location not found.
"uuid"Responses
Location deleted
Update an office location
Partial update of a location. address, when sent, replaces the whole address object. Setting is_primary: true clears the previous primary in the same transaction.
Requires permission: org.manage_locations
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"A non-UUID answers 404 Location not found.
"uuid"Request Body
Responses
Location updated
Start or resume Stripe Connect onboarding
Creates the organization's Stripe Express account (business type company) if it has none, or reuses the existing one, and returns a fresh single-use onboarding link. Safe to call repeatedly — each call returns a new link. If the stored account no longer exists on Stripe a new one is created in its place.
The organization must have verification_status: verified, and the features.org_level_stripe_connect flag must be on (503 otherwise).
Requires permission: org.manage_payouts (organization owners only)
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Responses
Onboarding link created
Get Stripe Connect status
Whether the organization can take charges and receive payouts. Reads the account live from Stripe and refreshes the stored flags. If Stripe cannot be reached, the last stored flags are returned instead and the Stripe-only fields (defaultCurrency, country, businessType, requirementsCurrentlyDue) are absent. With no account yet the body is { "data": { "connected": false } }.
Requires permission: org.read_payouts
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Responses
Connect status
List child organizations
Organizations whose parent is this one, newest first. Always empty for a company; only a conglomerate has children.
Requires permission: org.read
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Responses
Child organizations
Create a child organization
Creates a new company under this conglomerate. Validation is the same as POST /organizations, except that the new organization is always a company (kind is ignored once it passes validation) and sending parent_organization_id in the body is rejected — the parent is always the {slug} organization. The caller becomes org_owner of the child. The child starts with verification_status: pending; the first DBA becomes its default and the first location its primary.
Requires a verified email address.
Requires permission: org.manage_children (organization owners only)
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Request Body
Responses
Child organization created
List verification documents
The organization's verification documents in every state except superseded, newest first, including review outcome and whether each is shown on the public profile.
Financial documents — w9, voided_check and other — are listed only when the caller also holds org.upload_documents; otherwise they are left out of the list. ein_letter and 501c3_determination are listed with org.read alone.
Requires permission: org.read
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Responses
Documents
Upload a verification document
Uploads a document for platform review as base64 JSON. It is stored privately and enters the review queue as pending. Uploading a doc_type the organization already has pending or approved marks the older one superseded. Approval of both ein_letter and 501c3_determination is what verifies the organization.
Size limit: 10 MB decoded by default, but the JSON body itself is capped at 10 MB, so in practice a file must stay under about 7.5 MB to fit once base64-encoded — larger bodies get 413 before the handler runs.
Requires permission: org.upload_documents
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"Request Body
Responses
Document uploaded
Download a verification document
Streams the stored file with its original Content-Type and, when a filename was recorded, Content-Disposition: attachment. A document belonging to a different organization answers 404.
A w9, voided_check or other document can be downloaded only by a caller who also holds org.upload_documents; anyone else gets 404, as if it did not exist.
Requires permission: org.read
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"A non-UUID answers 404 Document not found.
"uuid"Responses
The file
Delete a pending verification document
Withdraws a document that is still pending. Approved and rejected documents are kept for the audit trail and cannot be deleted — they answer 404 like a missing document.
Requires permission: org.upload_documents
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"A non-UUID answers 404 Document not found.
"uuid"Responses
Document deleted
Show or hide a document on the public profile
Sets the document's public-visibility flag. The public profile (GET /organizations/{id}/documents/public) lists a document only when it is both flagged public and approved, so the flag can be set ahead of review.
Requires permission: org.upload_documents
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
The organization's slug (not its UUID).
"local-food-bank-a1b2c3""^[a-z0-9][a-z0-9-]{0,254}$"A non-UUID answers 404 Document not found.
"uuid"Request Body
Responses
Visibility updated