Sections

Interests

Used by the website. These routes don't accept an API key.

GET/interests/interests

Get Interests

Website sign-in only

Response: any

curl
curl 'https://api.papervantage.com/interests/interests' \
  -H "Authorization: Bearer $COGNITO_ACCESS_TOKEN"

POST/interests/seed

Sets initial interest weights for a just-signed-up user. The frontend

Website sign-in only

calls this once, right after Cognito sign-up completes, with the interests picked during the sign-up form -- this used to happen inline in the old /auth/register endpoint before Cognito owned sign-up. Also used by the account page's "Add interests" picker, so the same call can now race a second tab or a retried request.

The per-keyword check-then-insert below isn't atomic across two separate sessions, and UserInterest has a unique (user_id, keyword) constraint -- retried the same way set_paper_rating retries the equivalent (user_id, paper_id) race in services/interests.py, so the loser of the race re-checks against whatever row the winner left behind and no-ops instead of 500ing on an unhandled IntegrityError.

Reads user.id into a plain local before the loop rather than inside it: db.rollback() expires every ORM object attached to the session, including `user` (loaded by the get_current_user dependency on this same session), so accessing user.id again on a retry attempt without an explicit await raises MissingGreenlet under the async driver instead of transparently refreshing.

Request body (JSON)
FieldTypeDescription
interests *string[]

Response: any

curl
curl -X POST 'https://api.papervantage.com/interests/seed' \
  -H "Authorization: Bearer $COGNITO_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"interests":["<interests>"]}'

Next: Media