Fur Affinity APIfuraffinity.com ↗
Retrieve Fur Affinity user profiles and artwork submission details via API. Access stats, ratings, keywords, image URLs, and more with two structured endpoints.
What is the Fur Affinity API?
The Fur Affinity API provides two endpoints for retrieving structured data from furaffinity.com: get_profile returns 8 fields including account statistics, avatar URL, bio text, and registration timestamp for any public user, while get_artwork returns submission metadata such as content rating, keyword tags, view counts, and file size for any numeric artwork ID.
curl -X GET 'https://api.parse.bot/scraper/d7cf673b-7506-49a2-9022-c954c39593bd/get_profile?username=fender' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace furaffinity-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: Fur Affinity SDK — fetch artwork details and artist profile."""
from parse_apis.furaffinity_com_api import FurAffinity, InputNotFound
client = FurAffinity()
# Fetch a specific artwork submission by its numeric ID.
try:
artwork = client.artworks.get(artwork_id="1345722")
except InputNotFound:
print("Artwork not found")
raise
print(artwork.title, f"by {artwork.artist_display_name}")
print(f" views={artwork.views} favorites={artwork.favorites} comments={artwork.comments}")
print(f" rating={artwork.rating} category={artwork.category}")
print(f" keywords={artwork.keywords}")
# Navigate to the artist's profile using the username from the artwork.
profile = client.profiles.get(username=artwork.artist_username)
print(f"\nProfile: {profile.display_name} ({profile.user_role})")
print(f" registered: {profile.registered_date}")
print(f" stats: {profile.stats.views} views, {profile.stats.submissions} submissions")
print("\nexercised: artworks.get / profiles.get")
Retrieve a Fur Affinity user's public profile including display name, role, registration date, avatar, bio text, and account statistics (views, submissions, favorites, comments earned/made, journals). Makes one request per call.
| Param | Type | Description |
|---|---|---|
| usernamerequired | string | The user's URL-safe username (lowercase handle as it appears in furaffinity.net/user/<username>/). |
{
"type": "object",
"fields": {
"stats": "object — account statistics with keys: views, submissions, favorites, comments_earned, comments_made, journals",
"username": "string — the requested username handle",
"user_role": "string — account role (e.g. Watcher, Member)",
"avatar_url": "string — full URL to the user's avatar image",
"display_name": "string — the user's displayed name",
"profile_text": "string — the user's profile bio/description text",
"registered_date": "string — registration date in human-readable form",
"registered_timestamp": "integer — Unix timestamp of registration"
},
"sample": {
"data": {
"stats": {
"views": 1175833,
"journals": 253,
"favorites": 9263,
"submissions": 22,
"comments_made": 1136,
"comments_earned": 63828
},
"username": "fender",
"user_role": "Watcher",
"avatar_url": "https://a.furaffinity.net/1424255659/fender.gif",
"display_name": "Fender",
"profile_text": "THIS IS A MASCOT/NEWS ACCOUNT...",
"registered_date": "December 4, 2005 06:49:59 PM",
"registered_timestamp": 1133740199
},
"status": "success"
}
}About the Fur Affinity API
User Profile Data
The get_profile endpoint accepts a username parameter — the lowercase handle as it appears in furaffinity.net/user/<username>/ — and returns a structured object covering the user's display_name, user_role, avatar_url, and profile_text. The stats object bundles six counters: views, submissions, favorites, comments_earned, comments_made, and journals. Registration data is available as both a human-readable registered_date string and a Unix registered_timestamp integer, which is useful for sorting or age calculations.
Artwork Submission Data
The get_artwork endpoint accepts an artwork_id — the numeric ID from furaffinity.net/view/<artwork_id>/ — and returns submission-level metadata. Response fields include title, rating (one of General, Mature, or Adult), category, species, theme, file_size, and an array of keywords tags. Engagement metrics come back as integers: views, comments, and favorites. This makes the endpoint suitable for building submission indexes, tag-based classifiers, or content moderation tooling.
Coverage Notes
Both endpoints operate on public Fur Affinity data. The profile endpoint reflects what is visible on a user's public page — private or hidden accounts will not return data. The artwork endpoint covers individual submissions identified by their numeric ID; there is no batch or search endpoint in the current API surface.
The Fur Affinity API is a managed, monitored endpoint for furaffinity.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when furaffinity.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official furaffinity.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Build an artist discovery tool that ranks creators by submission count and favorites using
get_profilestats - Classify artwork by content maturity using the
ratingfield fromget_artworkfor moderation pipelines - Generate tag clouds or keyword frequency reports from the
keywordsarray across multiple submissions - Track account growth over time by periodically polling
viewsandsubmissionsstats fromget_profile - Index submission metadata including
category,species, andthemeto power a third-party search interface - Identify new community members by comparing
registered_timestampvalues across a set of usernames - Aggregate
favoritesandcommentscounts fromget_artworkto surface trending or high-engagement submissions
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Fur Affinity have an official developer API?+
What does the `get_artwork` endpoint return for content rating?+
rating field returns one of three string values: General, Mature, or Adult, reflecting the rating the submitting artist assigned to the work. No further content filtering is applied — the field mirrors what is shown on the public submission page.Does the API support searching or listing submissions for a user?+
get_artwork and profile data via get_profile. It does not include an endpoint for listing all submissions by a given artist. You can fork it on Parse and revise to add the missing endpoint.Are journal entries or shouts accessible through the API?+
get_profile endpoint returns a journals count within the stats object, but the content of individual journals and shouts is not exposed. You can fork it on Parse and revise to add the missing endpoint.