Resumly¶
The public pay-per-use client — the main entry point for all SDK operations.
ResumlyClient is an alias of this class.
Resumly ¶
Resumly(api_key: Optional[str] = None, base_url: str = _DEFAULT_BASE_URL, timeout: int = 180, max_retries: int = 3)
Client for the Resumly public API (/api/v1).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_key
|
str
|
Your Resumly API key (starts with |
None
|
base_url
|
str
|
API base URL. Defaults to |
_DEFAULT_BASE_URL
|
timeout
|
int
|
HTTP request timeout in seconds. Defaults to 180 (AI operations can take a couple of minutes). |
180
|
max_retries
|
int
|
Auto-retry count on 429 (rate limit), honoring |
3
|
Examples:
>>> from resumly import Resumly
>>> client = Resumly(api_key="rly_...")
>>> client.balance()
{'balance_usd': 5.0, ...}
usage ¶
Paginated ledger of metered charges, newest first. Free.
create_key ¶
Create a new API key. The full key is shown exactly once.
buy_credit ¶
Create a Stripe checkout for a wallet top-up; returns the checkout URL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amount
|
str or int
|
One of |
required |
upload_base_resume ¶
Upload and parse a PDF/DOCX base resume. $0.05.
update_base_resume ¶
Replace the parsed base resume data. Free.
Pass expected_active_upload_id for optimistic concurrency: the
update is rejected if another upload became active in the meantime.
autofill_profile ¶
Your auto-apply answer profile (work auth, EEO, phone, etc.). Free.
update_autofill_profile ¶
Update the auto-apply answer profile. Free.
set_instructions ¶
Set custom tailoring instructions applied to every tailor. Free.
queries ¶
List saved searches with refresh metadata (last_refreshed_at,
latest_job_posted, new_jobs_last_run, consecutive_empty_runs,
supply_preview) so you can decide whether a refresh is worth $0.05.
Free.
create_query ¶
Create a saved search from structured filters. Free.
To build filters from plain English first, call :meth:interpret and
pass the returned draft_patch fields here. Jobs are fetched only
when you :meth:refresh the query.
supply_check ¶
Count how many jobs a draft search shape would match. Free, cached
~10 minutes. Same filter shape as :meth:create_query (name optional).
interpret ¶
Turn plain English into validated search filters. Free (budget-capped).
Returns a draft_patch you can pass to :meth:create_query, plus
assumptions made and asks that could not be mapped.
refresh ¶
Fetch fresh jobs for a saved search. $0.05, returns 202.
Poll :meth:query until last_refreshed_at advances, then read
:meth:jobs. A 429 means a run is already in flight (not charged).
jobs ¶
Your matched-jobs board — every job your searches found, scored against your resume. Free.
Supported filters: query_id, auto_apply (true = only jobs the
auto-apply fleet can submit), remote_only, last_n_days,
date_from, date_to, sort_by ('match' or 'date'),
is_saved, min_match_score / max_match_score (0..1),
application_status, keyword, organization,
has_salary_info, min_annual_salary, visa_sponsorship_only,
hide_completed.
job_stats ¶
Board statistics: status lanes, sources, match-score bands. Free.
job ¶
Full job detail: description, url, score insight, organization. Free.
import_job ¶
import_job(url: str, raw_text: Optional[str] = None, *, idempotency_key: Optional[str] = None) -> dict
Import an outside posting into your feed, parsed and match-scored. $0.05.
Pass just url (Resumly fetches and parses it) or url plus
raw_text (parsed directly; the url is still used for dedupe).
Raises :class:DuplicateRequestError (409) if the URL is already in
your feed — you are not charged.
tailor ¶
tailor(job_id: Optional[str] = None, *, url: Optional[str] = None, description: Optional[str] = None, llm_model: Optional[str] = None, idempotency_key: Optional[str] = None) -> dict
Create a tailored resume. $0.25.
Three ways to point at a job:
tailor(job_id)— tailor for a job already on your board (POST /jobs/{id}/tailor).tailor(url=...)— tailor for an outside posting URL.tailor(description=...)— tailor for raw job-description text.
resumes ¶
List your tailored resumes, newest first. Free.
download ¶
Download the tailored resume as DOCX bytes. Free.
If path is given the bytes are also written to disk.
cover_letter ¶
Generate a cover letter for a tailored resume. $0.10.
export_pdf ¶
export_pdf(resume_id: str, document_type: str = 'resume', *, idempotency_key: Optional[str] = None) -> dict
Start a PDF export of the resume or cover letter. $0.02, returns 202
with an operation_id — poll :meth:operation or use
:meth:wait_operation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
document_type
|
str
|
|
'resume'
|
get_operation ¶
Status of any async operation. Free.
status is one of queued, running, succeeded,
failed, or needs_attention (an application a human must
finish — not a failure; the reservation stays open).
operations ¶
Your recent async operations, newest first. Free.
wait ¶
wait(operation_id: str, *, timeout: int = 600, poll_interval: float = 3.0, raise_on_failure: bool = True) -> dict
Block until an operation reaches a terminal state, then return it.
needs_attention is deliberately NOT terminal: an escalated
application is still live. Set timeout to how long you are
willing to wait for one; applications can legitimately take minutes.
Raises :class:ResumlyError on timeout, or on a failed operation
unless raise_on_failure=False.
operation ¶
Status of an async export operation, via the legacy per-resume
route. Prefer :meth:get_operation, which works for every async
operation. Free.
wait_operation ¶
wait_operation(resume_id: str, operation_id: str, *, timeout: int = 180, poll_interval: float = 2.0) -> dict
Poll an export operation until it leaves the pending states.
Returns the final operation document (check its status and result
URL). Raises :class:ResumlyError if timeout seconds pass first.
translate ¶
translate(resume_id: str, target_language: str, document_type: Optional[str] = None, *, idempotency_key: Optional[str] = None) -> dict
Translate a tailored resume (or cover letter) to another language. $0.10.
rewrite ¶
Rewrite your base resume following free-form instructions. $0.50.
interview_questions ¶
Generate interview questions for a job on your board. $0.10.
get_interview_questions ¶
Read stored interview questions. Free.
interview_answer ¶
interview_answer(job_id: str, question_index: int, answer: str, *, idempotency_key: Optional[str] = None) -> dict
Get AI feedback on your answer to a generated question. $0.05.
company_research ¶
Run company research for a job's employer. $0.25.
get_company_research ¶
Read stored company research. Free.
eligible_jobs ¶
eligible_jobs(page: int = 1, page_size: int = 25, *, query_id: Optional[str] = None, min_match_score: Optional[float] = None, keyword: Optional[str] = None, saved_only: bool = False) -> dict
Jobs the auto-apply fleet can submit for you. Free.
apply ¶
Queue an auto-apply submission. $0.50 is reserved and billed only on a confirmed submission; failures are refunded.
Returns 202 with a queue_job_id — track it via :meth:applications.
applications ¶
applications(status: Optional[str] = None, job_ids: Optional[List[str]] = None, page: int = 1, page_size: int = 25) -> dict
List your auto-apply applications with status. Free.
cancel_application ¶
Cancel a queued application (the reservation is released). Free.
retry_application ¶
Retry a failed application (a fresh $0.50 reservation applies).
enable_autopilot ¶
Enable autopilot (e.g. job_queries=[...], min_match_score=70).
Autopilot runs consume the same wallet: each submission bills like
:meth:apply, each search run like :meth:refresh.
autopilot_activity ¶
Per-job autopilot activity, paginated. Free.
autopilot_runs ¶
Autopilot run history, paginated. Free.
inbox_emails ¶
inbox_emails(page: int = 1, page_size: int = 25, *, category: Optional[str] = None, categories: Optional[List[str]] = None, is_read: Optional[bool] = None, search: Optional[str] = None, job_id: Optional[str] = None) -> dict
Classified employer emails (interview invites, rejections, offers, assessments...). Free.
categories (a list, sent CSV) overrides category.
reply_email ¶
Reply to an employer email (e.g. body_text=... or
body_html=...). Free.
compose_email ¶
Send a new email from your managed inbox (to=[...], subject=...,
body_text=...). Free.
AgencyClient¶
B2B agency console — provision and manage client profiles with a full-scope
agency key (from resumly.agency import AgencyClient).
AgencyClient ¶
AgencyClient(api_key: Optional[str] = None, base_url: str = _DEFAULT_BASE_URL, timeout: int = 180, max_retries: int = 3)
Client for the Resumly agency (tenant-admin) API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_key
|
str
|
The agency admin's full-scope API key. Falls back to the
|
None
|
base_url
|
str
|
API base URL. Defaults to |
_DEFAULT_BASE_URL
|
timeout
|
int
|
HTTP request timeout in seconds. Defaults to 180. |
180
|
max_retries
|
int
|
Auto-retry count on 429, honoring |
3
|
create_client_profile ¶
create_client_profile(name: str, email: str, *, external_id: Optional[str] = None, applications_per_day: Optional[int] = None, account_type: Optional[str] = None, location: Optional[str] = None) -> dict
Provision a client profile under your agency tenant.
Returns the profile plus api_key — shown exactly once. Store it;
it cannot be retrieved later (use :meth:rotate_client_key if lost).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The client's full name. |
required |
email
|
str
|
The client's apply email. Applications are submitted under this identity and employer replies are routed to it. |
required |
external_id
|
str
|
Your own reference id for this client, echoed back on webhooks. |
None
|
applications_per_day
|
int
|
Per-client daily auto-apply cap. Defaults to the plan tier's cap. |
None
|
list_client_profiles ¶
List client profiles in your agency tenant.
update_client_profile ¶
update_client_profile(profile_id: str, *, status: Optional[str] = None, applications_per_day: Optional[int] = None, name: Optional[str] = None, external_id: Optional[str] = None) -> dict
Update a client profile.
status accepts "active" or "suspended". Suspending pauses
auto-apply, cancels queued jobs, and disables the client's API key
until reactivated.
delete_client_profile ¶
Delete a client profile. Keys are revoked; history is retained.
rotate_client_key ¶
Revoke the client's existing API keys and issue a new one.
get_agency_usage ¶
Billable successful applications per client for month (YYYY-MM).
get_webhook_config ¶
Current webhook configuration (the signing secret is never returned).
set_webhook_config ¶
set_webhook_config(url: str, *, secret: Optional[str] = None, enabled: bool = True, events: Optional[List[str]] = None) -> dict
Set the endpoint that receives application events.
On first save the generated signing secret is returned once. Verify
each delivery against the X-Resumly-Signature header, which is
t=<timestamp>,v1=<hmac_sha256(secret, f"{t}.{body}")>.
send_test_webhook ¶
Send a webhook.test event and return the delivery outcome.
list_webhook_deliveries ¶
list_webhook_deliveries(*, page: int = 1, page_size: int = 25, status: Optional[str] = None) -> dict
Recent webhook delivery attempts, newest first.