uphunt 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 UpHunt
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # uphunt
2
+
3
+ Official **UpHunt** SDK for Node.js & TypeScript — auto-apply to Upwork jobs, fetch archived job & client data, and generate AI proposals, all from your own stack.
4
+
5
+ - 📚 Full API docs: **https://uphunt.io/docs**
6
+ - 🔑 Get an API key: **Dashboard → Auto-Apply → API & Webhooks**
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm install uphunt
12
+ # or: pnpm add uphunt / yarn add uphunt / bun add uphunt
13
+ ```
14
+
15
+ Requires Node 18+ (uses the built-in `fetch`). Fully typed; works in ESM, CommonJS, and edge runtimes.
16
+
17
+ ## Quickstart
18
+
19
+ ```ts
20
+ import { UpHunt } from 'uphunt'
21
+
22
+ const uphunt = new UpHunt({ apiKey: process.env.UPHUNT_API_KEY })
23
+
24
+ // Apply to a job
25
+ const { queueId, creditsRemaining } = await uphunt.apply({
26
+ jobId: '~022053140178050136031',
27
+ coverLetter: "Hi — I'd love to help with this project…",
28
+ proposal: { hourlyRate: 65, timeline: '1 to 3 months' },
29
+ })
30
+
31
+ // Poll status
32
+ const status = await uphunt.status({ queueId })
33
+ console.log(status.applicationStatus) // 'processing' | 'applied' | …
34
+ ```
35
+
36
+ If you omit `apiKey`, the client reads `UPHUNT_API_KEY` from the environment.
37
+
38
+ ## Methods
39
+
40
+ | Method | REST endpoint |
41
+ |---|---|
42
+ | `apply(input)` | `POST /api/auto-apply-v2/apply` |
43
+ | `status({ queueId, jobId })` | `GET /api/auto-apply-v2/status` |
44
+ | `appliedJobs({ limit, offset, status })` | `GET /api/auto-apply-v2/applied-jobs` |
45
+ | `generateProposal(input)` | `POST /api/auto-apply-v2/generate-proposal` |
46
+ | `freelancers()` | `GET /api/auto-apply-v2/freelancers` |
47
+ | `getJob(ciphertext)` | `GET /api/jobs/by-ciphertext` |
48
+ | `getClientJobs(companyId)` | `GET /api/clients/:companyId/jobs` |
49
+
50
+ ## Error handling
51
+
52
+ Any non-2xx response throws an `UpHuntError` with `.status` and `.body`:
53
+
54
+ ```ts
55
+ import { UpHunt, UpHuntError } from 'uphunt'
56
+
57
+ try {
58
+ await uphunt.apply({ jobId: '~01abc', coverLetter: '…' })
59
+ } catch (err) {
60
+ if (err instanceof UpHuntError) {
61
+ console.error(err.status, err.message, err.body)
62
+ }
63
+ }
64
+ ```
65
+
66
+ ## Generating a proposal then applying
67
+
68
+ ```ts
69
+ const { proposal } = await uphunt.generateProposal({ jobId: '~01abc', reasoningEffort: 'medium' })
70
+ await uphunt.apply({ jobId: '~01abc', coverLetter: proposal })
71
+ ```
72
+
73
+ ## License
74
+
75
+ MIT © UpHunt
package/dist/index.cjs ADDED
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ UpHunt: () => UpHunt,
24
+ UpHuntError: () => UpHuntError,
25
+ default: () => index_default
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+ var UpHuntError = class extends Error {
29
+ status;
30
+ body;
31
+ constructor(message, status, body) {
32
+ super(message);
33
+ this.name = "UpHuntError";
34
+ this.status = status;
35
+ this.body = body;
36
+ }
37
+ };
38
+ function envApiKey() {
39
+ return typeof process !== "undefined" ? process.env?.UPHUNT_API_KEY : void 0;
40
+ }
41
+ var UpHunt = class {
42
+ apiKey;
43
+ baseUrl;
44
+ fetchImpl;
45
+ constructor(options = {}) {
46
+ const apiKey = options.apiKey ?? envApiKey();
47
+ if (!apiKey) {
48
+ throw new Error(
49
+ "UpHunt: missing API key. Pass `new UpHunt({ apiKey })` or set UPHUNT_API_KEY."
50
+ );
51
+ }
52
+ this.apiKey = apiKey;
53
+ this.baseUrl = (options.baseUrl ?? "https://uphunt.io").replace(/\/+$/, "");
54
+ const f = options.fetch ?? globalThis.fetch;
55
+ if (!f) {
56
+ throw new Error("UpHunt: no global fetch found. Use Node 18+ or pass `{ fetch }`.");
57
+ }
58
+ this.fetchImpl = f;
59
+ }
60
+ async request(method, path, opts = {}) {
61
+ const url = new URL(this.baseUrl + path);
62
+ if (opts.query) {
63
+ for (const [k, v] of Object.entries(opts.query)) {
64
+ if (v !== void 0) url.searchParams.set(k, String(v));
65
+ }
66
+ }
67
+ const headers = { "x-api-key": this.apiKey };
68
+ if (opts.body !== void 0) headers["content-type"] = "application/json";
69
+ const res = await this.fetchImpl(url, {
70
+ method,
71
+ headers,
72
+ body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0
73
+ });
74
+ const text = await res.text();
75
+ let data;
76
+ try {
77
+ data = text ? JSON.parse(text) : void 0;
78
+ } catch {
79
+ data = text;
80
+ }
81
+ if (!res.ok) {
82
+ const message = data && typeof data === "object" && "error" in data ? String(data.error) : res.statusText || `HTTP ${res.status}`;
83
+ throw new UpHuntError(message, res.status, data);
84
+ }
85
+ return data;
86
+ }
87
+ /** Queue a proposal submission. One credit is deducted on success. */
88
+ apply(input) {
89
+ return this.request("POST", "/api/auto-apply-v2/apply", { body: input });
90
+ }
91
+ /** Poll an application's status by `queueId` or `jobId`. */
92
+ status(params) {
93
+ return this.request("GET", "/api/auto-apply-v2/status", {
94
+ query: params
95
+ });
96
+ }
97
+ /** Paginated list of jobs you've applied to. */
98
+ appliedJobs(params = {}) {
99
+ return this.request("GET", "/api/auto-apply-v2/applied-jobs", {
100
+ query: params
101
+ });
102
+ }
103
+ /** Generate an AI cover letter for a job. */
104
+ generateProposal(input) {
105
+ return this.request(
106
+ "POST",
107
+ "/api/auto-apply-v2/generate-proposal",
108
+ { body: input }
109
+ );
110
+ }
111
+ /** List the freelancers in your agency and their profiles. */
112
+ freelancers() {
113
+ return this.request("GET", "/api/auto-apply-v2/freelancers");
114
+ }
115
+ /** Fetch a single archived Upwork job by its ciphertext (`~02…`). */
116
+ getJob(ciphertext) {
117
+ return this.request("GET", "/api/jobs/by-ciphertext", { query: { cipher: ciphertext } });
118
+ }
119
+ /** Fetch a buyer's open jobs and work history by Upwork companyId. */
120
+ getClientJobs(companyId) {
121
+ return this.request(
122
+ "GET",
123
+ `/api/clients/${encodeURIComponent(companyId)}/jobs`
124
+ );
125
+ }
126
+ };
127
+ var index_default = UpHunt;
128
+ // Annotate the CommonJS export names for ESM import in node:
129
+ 0 && (module.exports = {
130
+ UpHunt,
131
+ UpHuntError
132
+ });
133
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Official UpHunt SDK for Node.js & TypeScript.\n *\n * Docs: https://uphunt.io/docs\n *\n * ```ts\n * import { UpHunt } from 'uphunt'\n * const uphunt = new UpHunt({ apiKey: process.env.UPHUNT_API_KEY })\n * const { queueId } = await uphunt.apply({ jobId: '~01abc', coverLetter: 'Hi…' })\n * ```\n */\n\nexport type Timeline =\n | 'Less than 1 month'\n | '1 to 3 months'\n | '3 to 6 months'\n | 'More than 6 months'\n\nexport type ReasoningEffort = 'low' | 'medium' | 'high'\n\nexport type ApplicationStatus =\n | 'processing'\n | 'applied'\n | 'failed'\n | 'not_available'\n | 'not_eligible'\n | 'not_enough_connects'\n | 'logged_out'\n\nexport interface Proposal {\n /** USD hourly bid (hourly jobs only). */\n hourlyRate?: number\n /** USD fixed bid (fixed-price jobs only). */\n fixedBid?: number\n timeline?: Timeline\n /** Extra Connects to boost the proposal's visibility. */\n boostBids?: number\n}\n\nexport interface QuestionAnswer {\n /** 0-indexed position from the job's `screeningQuestions`. */\n position: number\n answer: string\n}\n\nexport interface ApplyInput {\n /** Ciphertext (`~01abc…`), full Upwork URL, or processed job UUID. */\n jobId: string\n coverLetter: string\n /** Freelancer profileId from `freelancers()`. Defaults to the primary profile. */\n profileId?: string\n proposal?: Proposal\n /** AI-answer remaining screening questions. */\n autoFillOtherQuestions?: boolean\n /** Explicit answers for screening questions. */\n questionAnswers?: QuestionAnswer[]\n}\n\nexport interface ApplyResponse {\n success: boolean\n queueId: string\n creditsRemaining?: number\n message?: string\n}\n\nexport interface StatusResponse {\n jobId: string | null\n processedJobId: string | null\n applicationStatus: ApplicationStatus | null\n applicationStatusMessage: string | null\n queueId: string | null\n appliedAt: number | null\n processedAt: number | null\n errorMessage: string | null\n}\n\nexport interface AppliedJob {\n jobId: string | null\n processedJobId: string | null\n title: string | null\n url: string | null\n platform: 'upwork' | 'linkedin'\n applicationStatus: ApplicationStatus | null\n applicationStatusMessage: string | null\n matchingScore: number | null\n queueId: string | null\n appliedAt: number | null\n processedAt: number | null\n errorMessage: string | null\n coverLetter: string | null\n createdAt: number | null\n}\n\nexport interface AppliedJobsResponse {\n jobs: AppliedJob[]\n total: number\n limit: number\n offset: number\n}\n\nexport interface AppliedJobsParams {\n limit?: number\n offset?: number\n status?: ApplicationStatus\n}\n\nexport interface GenerateProposalInput {\n /** Ciphertext, URL, or processed job UUID. Required unless title+description given. */\n jobId?: string\n jobTitle?: string\n jobDescription?: string\n /** Job listener ID whose custom prompt should be used. */\n feedId?: string\n reasoningEffort?: ReasoningEffort\n}\n\nexport interface GenerateProposalResponse {\n success: boolean\n proposal: string\n}\n\nexport interface FreelancerProfile {\n type: 'default'\n name: string\n hourlyRate: number | null\n currency: string\n profileId: string\n}\n\nexport interface Freelancer {\n id: string\n name: string\n avatarUrl: string | null\n baseHourlyRate: number | null\n profiles: FreelancerProfile[]\n}\n\nexport interface FreelancersResponse {\n freelancers: Freelancer[]\n}\n\n/** Full archived RawUpworkJob document. Shape is open-ended; key fields typed loosely. */\nexport type Job = Record<string, unknown>\n\nexport interface ClientJobsResponse {\n companyId: string\n lastSyncedAt: number\n buyer: Record<string, unknown>\n openJobs: Array<Record<string, unknown>>\n workHistory: Array<Record<string, unknown>>\n archivedCiphers: string[]\n archivedJobIds: string[]\n}\n\nexport interface UpHuntOptions {\n /** Your UpHunt API key. Falls back to `process.env.UPHUNT_API_KEY`. */\n apiKey?: string\n /** API base URL. Defaults to `https://uphunt.io`. */\n baseUrl?: string\n /** Custom fetch implementation (defaults to global `fetch`; Node 18+). */\n fetch?: typeof fetch\n}\n\n/** Thrown for any non-2xx API response. */\nexport class UpHuntError extends Error {\n readonly status: number\n readonly body: unknown\n constructor(message: string, status: number, body: unknown) {\n super(message)\n this.name = 'UpHuntError'\n this.status = status\n this.body = body\n }\n}\n\ntype Query = Record<string, string | number | boolean | undefined>\n\nfunction envApiKey(): string | undefined {\n return typeof process !== 'undefined' ? process.env?.UPHUNT_API_KEY : undefined\n}\n\nexport class UpHunt {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly fetchImpl: typeof fetch\n\n constructor(options: UpHuntOptions = {}) {\n const apiKey = options.apiKey ?? envApiKey()\n if (!apiKey) {\n throw new Error(\n 'UpHunt: missing API key. Pass `new UpHunt({ apiKey })` or set UPHUNT_API_KEY.',\n )\n }\n this.apiKey = apiKey\n this.baseUrl = (options.baseUrl ?? 'https://uphunt.io').replace(/\\/+$/, '')\n const f = options.fetch ?? globalThis.fetch\n if (!f) {\n throw new Error('UpHunt: no global fetch found. Use Node 18+ or pass `{ fetch }`.')\n }\n this.fetchImpl = f\n }\n\n private async request<T>(\n method: 'GET' | 'POST',\n path: string,\n opts: { query?: Query; body?: unknown } = {},\n ): Promise<T> {\n const url = new URL(this.baseUrl + path)\n if (opts.query) {\n for (const [k, v] of Object.entries(opts.query)) {\n if (v !== undefined) url.searchParams.set(k, String(v))\n }\n }\n\n const headers: Record<string, string> = { 'x-api-key': this.apiKey }\n if (opts.body !== undefined) headers['content-type'] = 'application/json'\n\n const res = await this.fetchImpl(url, {\n method,\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n })\n\n const text = await res.text()\n let data: unknown\n try {\n data = text ? JSON.parse(text) : undefined\n } catch {\n data = text\n }\n\n if (!res.ok) {\n const message =\n data && typeof data === 'object' && 'error' in data\n ? String((data as { error: unknown }).error)\n : res.statusText || `HTTP ${res.status}`\n throw new UpHuntError(message, res.status, data)\n }\n\n return data as T\n }\n\n /** Queue a proposal submission. One credit is deducted on success. */\n apply(input: ApplyInput): Promise<ApplyResponse> {\n return this.request<ApplyResponse>('POST', '/api/auto-apply-v2/apply', { body: input })\n }\n\n /** Poll an application's status by `queueId` or `jobId`. */\n status(params: { queueId?: string; jobId?: string }): Promise<StatusResponse> {\n return this.request<StatusResponse>('GET', '/api/auto-apply-v2/status', {\n query: params as Query,\n })\n }\n\n /** Paginated list of jobs you've applied to. */\n appliedJobs(params: AppliedJobsParams = {}): Promise<AppliedJobsResponse> {\n return this.request<AppliedJobsResponse>('GET', '/api/auto-apply-v2/applied-jobs', {\n query: params as Query,\n })\n }\n\n /** Generate an AI cover letter for a job. */\n generateProposal(input: GenerateProposalInput): Promise<GenerateProposalResponse> {\n return this.request<GenerateProposalResponse>(\n 'POST',\n '/api/auto-apply-v2/generate-proposal',\n { body: input },\n )\n }\n\n /** List the freelancers in your agency and their profiles. */\n freelancers(): Promise<FreelancersResponse> {\n return this.request<FreelancersResponse>('GET', '/api/auto-apply-v2/freelancers')\n }\n\n /** Fetch a single archived Upwork job by its ciphertext (`~02…`). */\n getJob(ciphertext: string): Promise<Job> {\n return this.request<Job>('GET', '/api/jobs/by-ciphertext', { query: { cipher: ciphertext } })\n }\n\n /** Fetch a buyer's open jobs and work history by Upwork companyId. */\n getClientJobs(companyId: string): Promise<ClientJobsResponse> {\n return this.request<ClientJobsResponse>(\n 'GET',\n `/api/clients/${encodeURIComponent(companyId)}/jobs`,\n )\n }\n}\n\nexport default UpHunt\n"],"mappings":"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","names":[]}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Official UpHunt SDK for Node.js & TypeScript.
3
+ *
4
+ * Docs: https://uphunt.io/docs
5
+ *
6
+ * ```ts
7
+ * import { UpHunt } from 'uphunt'
8
+ * const uphunt = new UpHunt({ apiKey: process.env.UPHUNT_API_KEY })
9
+ * const { queueId } = await uphunt.apply({ jobId: '~01abc', coverLetter: 'Hi…' })
10
+ * ```
11
+ */
12
+ type Timeline = 'Less than 1 month' | '1 to 3 months' | '3 to 6 months' | 'More than 6 months';
13
+ type ReasoningEffort = 'low' | 'medium' | 'high';
14
+ type ApplicationStatus = 'processing' | 'applied' | 'failed' | 'not_available' | 'not_eligible' | 'not_enough_connects' | 'logged_out';
15
+ interface Proposal {
16
+ /** USD hourly bid (hourly jobs only). */
17
+ hourlyRate?: number;
18
+ /** USD fixed bid (fixed-price jobs only). */
19
+ fixedBid?: number;
20
+ timeline?: Timeline;
21
+ /** Extra Connects to boost the proposal's visibility. */
22
+ boostBids?: number;
23
+ }
24
+ interface QuestionAnswer {
25
+ /** 0-indexed position from the job's `screeningQuestions`. */
26
+ position: number;
27
+ answer: string;
28
+ }
29
+ interface ApplyInput {
30
+ /** Ciphertext (`~01abc…`), full Upwork URL, or processed job UUID. */
31
+ jobId: string;
32
+ coverLetter: string;
33
+ /** Freelancer profileId from `freelancers()`. Defaults to the primary profile. */
34
+ profileId?: string;
35
+ proposal?: Proposal;
36
+ /** AI-answer remaining screening questions. */
37
+ autoFillOtherQuestions?: boolean;
38
+ /** Explicit answers for screening questions. */
39
+ questionAnswers?: QuestionAnswer[];
40
+ }
41
+ interface ApplyResponse {
42
+ success: boolean;
43
+ queueId: string;
44
+ creditsRemaining?: number;
45
+ message?: string;
46
+ }
47
+ interface StatusResponse {
48
+ jobId: string | null;
49
+ processedJobId: string | null;
50
+ applicationStatus: ApplicationStatus | null;
51
+ applicationStatusMessage: string | null;
52
+ queueId: string | null;
53
+ appliedAt: number | null;
54
+ processedAt: number | null;
55
+ errorMessage: string | null;
56
+ }
57
+ interface AppliedJob {
58
+ jobId: string | null;
59
+ processedJobId: string | null;
60
+ title: string | null;
61
+ url: string | null;
62
+ platform: 'upwork' | 'linkedin';
63
+ applicationStatus: ApplicationStatus | null;
64
+ applicationStatusMessage: string | null;
65
+ matchingScore: number | null;
66
+ queueId: string | null;
67
+ appliedAt: number | null;
68
+ processedAt: number | null;
69
+ errorMessage: string | null;
70
+ coverLetter: string | null;
71
+ createdAt: number | null;
72
+ }
73
+ interface AppliedJobsResponse {
74
+ jobs: AppliedJob[];
75
+ total: number;
76
+ limit: number;
77
+ offset: number;
78
+ }
79
+ interface AppliedJobsParams {
80
+ limit?: number;
81
+ offset?: number;
82
+ status?: ApplicationStatus;
83
+ }
84
+ interface GenerateProposalInput {
85
+ /** Ciphertext, URL, or processed job UUID. Required unless title+description given. */
86
+ jobId?: string;
87
+ jobTitle?: string;
88
+ jobDescription?: string;
89
+ /** Job listener ID whose custom prompt should be used. */
90
+ feedId?: string;
91
+ reasoningEffort?: ReasoningEffort;
92
+ }
93
+ interface GenerateProposalResponse {
94
+ success: boolean;
95
+ proposal: string;
96
+ }
97
+ interface FreelancerProfile {
98
+ type: 'default';
99
+ name: string;
100
+ hourlyRate: number | null;
101
+ currency: string;
102
+ profileId: string;
103
+ }
104
+ interface Freelancer {
105
+ id: string;
106
+ name: string;
107
+ avatarUrl: string | null;
108
+ baseHourlyRate: number | null;
109
+ profiles: FreelancerProfile[];
110
+ }
111
+ interface FreelancersResponse {
112
+ freelancers: Freelancer[];
113
+ }
114
+ /** Full archived RawUpworkJob document. Shape is open-ended; key fields typed loosely. */
115
+ type Job = Record<string, unknown>;
116
+ interface ClientJobsResponse {
117
+ companyId: string;
118
+ lastSyncedAt: number;
119
+ buyer: Record<string, unknown>;
120
+ openJobs: Array<Record<string, unknown>>;
121
+ workHistory: Array<Record<string, unknown>>;
122
+ archivedCiphers: string[];
123
+ archivedJobIds: string[];
124
+ }
125
+ interface UpHuntOptions {
126
+ /** Your UpHunt API key. Falls back to `process.env.UPHUNT_API_KEY`. */
127
+ apiKey?: string;
128
+ /** API base URL. Defaults to `https://uphunt.io`. */
129
+ baseUrl?: string;
130
+ /** Custom fetch implementation (defaults to global `fetch`; Node 18+). */
131
+ fetch?: typeof fetch;
132
+ }
133
+ /** Thrown for any non-2xx API response. */
134
+ declare class UpHuntError extends Error {
135
+ readonly status: number;
136
+ readonly body: unknown;
137
+ constructor(message: string, status: number, body: unknown);
138
+ }
139
+ declare class UpHunt {
140
+ private readonly apiKey;
141
+ private readonly baseUrl;
142
+ private readonly fetchImpl;
143
+ constructor(options?: UpHuntOptions);
144
+ private request;
145
+ /** Queue a proposal submission. One credit is deducted on success. */
146
+ apply(input: ApplyInput): Promise<ApplyResponse>;
147
+ /** Poll an application's status by `queueId` or `jobId`. */
148
+ status(params: {
149
+ queueId?: string;
150
+ jobId?: string;
151
+ }): Promise<StatusResponse>;
152
+ /** Paginated list of jobs you've applied to. */
153
+ appliedJobs(params?: AppliedJobsParams): Promise<AppliedJobsResponse>;
154
+ /** Generate an AI cover letter for a job. */
155
+ generateProposal(input: GenerateProposalInput): Promise<GenerateProposalResponse>;
156
+ /** List the freelancers in your agency and their profiles. */
157
+ freelancers(): Promise<FreelancersResponse>;
158
+ /** Fetch a single archived Upwork job by its ciphertext (`~02…`). */
159
+ getJob(ciphertext: string): Promise<Job>;
160
+ /** Fetch a buyer's open jobs and work history by Upwork companyId. */
161
+ getClientJobs(companyId: string): Promise<ClientJobsResponse>;
162
+ }
163
+
164
+ export { type ApplicationStatus, type AppliedJob, type AppliedJobsParams, type AppliedJobsResponse, type ApplyInput, type ApplyResponse, type ClientJobsResponse, type Freelancer, type FreelancerProfile, type FreelancersResponse, type GenerateProposalInput, type GenerateProposalResponse, type Job, type Proposal, type QuestionAnswer, type ReasoningEffort, type StatusResponse, type Timeline, UpHunt, UpHuntError, type UpHuntOptions, UpHunt as default };
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Official UpHunt SDK for Node.js & TypeScript.
3
+ *
4
+ * Docs: https://uphunt.io/docs
5
+ *
6
+ * ```ts
7
+ * import { UpHunt } from 'uphunt'
8
+ * const uphunt = new UpHunt({ apiKey: process.env.UPHUNT_API_KEY })
9
+ * const { queueId } = await uphunt.apply({ jobId: '~01abc', coverLetter: 'Hi…' })
10
+ * ```
11
+ */
12
+ type Timeline = 'Less than 1 month' | '1 to 3 months' | '3 to 6 months' | 'More than 6 months';
13
+ type ReasoningEffort = 'low' | 'medium' | 'high';
14
+ type ApplicationStatus = 'processing' | 'applied' | 'failed' | 'not_available' | 'not_eligible' | 'not_enough_connects' | 'logged_out';
15
+ interface Proposal {
16
+ /** USD hourly bid (hourly jobs only). */
17
+ hourlyRate?: number;
18
+ /** USD fixed bid (fixed-price jobs only). */
19
+ fixedBid?: number;
20
+ timeline?: Timeline;
21
+ /** Extra Connects to boost the proposal's visibility. */
22
+ boostBids?: number;
23
+ }
24
+ interface QuestionAnswer {
25
+ /** 0-indexed position from the job's `screeningQuestions`. */
26
+ position: number;
27
+ answer: string;
28
+ }
29
+ interface ApplyInput {
30
+ /** Ciphertext (`~01abc…`), full Upwork URL, or processed job UUID. */
31
+ jobId: string;
32
+ coverLetter: string;
33
+ /** Freelancer profileId from `freelancers()`. Defaults to the primary profile. */
34
+ profileId?: string;
35
+ proposal?: Proposal;
36
+ /** AI-answer remaining screening questions. */
37
+ autoFillOtherQuestions?: boolean;
38
+ /** Explicit answers for screening questions. */
39
+ questionAnswers?: QuestionAnswer[];
40
+ }
41
+ interface ApplyResponse {
42
+ success: boolean;
43
+ queueId: string;
44
+ creditsRemaining?: number;
45
+ message?: string;
46
+ }
47
+ interface StatusResponse {
48
+ jobId: string | null;
49
+ processedJobId: string | null;
50
+ applicationStatus: ApplicationStatus | null;
51
+ applicationStatusMessage: string | null;
52
+ queueId: string | null;
53
+ appliedAt: number | null;
54
+ processedAt: number | null;
55
+ errorMessage: string | null;
56
+ }
57
+ interface AppliedJob {
58
+ jobId: string | null;
59
+ processedJobId: string | null;
60
+ title: string | null;
61
+ url: string | null;
62
+ platform: 'upwork' | 'linkedin';
63
+ applicationStatus: ApplicationStatus | null;
64
+ applicationStatusMessage: string | null;
65
+ matchingScore: number | null;
66
+ queueId: string | null;
67
+ appliedAt: number | null;
68
+ processedAt: number | null;
69
+ errorMessage: string | null;
70
+ coverLetter: string | null;
71
+ createdAt: number | null;
72
+ }
73
+ interface AppliedJobsResponse {
74
+ jobs: AppliedJob[];
75
+ total: number;
76
+ limit: number;
77
+ offset: number;
78
+ }
79
+ interface AppliedJobsParams {
80
+ limit?: number;
81
+ offset?: number;
82
+ status?: ApplicationStatus;
83
+ }
84
+ interface GenerateProposalInput {
85
+ /** Ciphertext, URL, or processed job UUID. Required unless title+description given. */
86
+ jobId?: string;
87
+ jobTitle?: string;
88
+ jobDescription?: string;
89
+ /** Job listener ID whose custom prompt should be used. */
90
+ feedId?: string;
91
+ reasoningEffort?: ReasoningEffort;
92
+ }
93
+ interface GenerateProposalResponse {
94
+ success: boolean;
95
+ proposal: string;
96
+ }
97
+ interface FreelancerProfile {
98
+ type: 'default';
99
+ name: string;
100
+ hourlyRate: number | null;
101
+ currency: string;
102
+ profileId: string;
103
+ }
104
+ interface Freelancer {
105
+ id: string;
106
+ name: string;
107
+ avatarUrl: string | null;
108
+ baseHourlyRate: number | null;
109
+ profiles: FreelancerProfile[];
110
+ }
111
+ interface FreelancersResponse {
112
+ freelancers: Freelancer[];
113
+ }
114
+ /** Full archived RawUpworkJob document. Shape is open-ended; key fields typed loosely. */
115
+ type Job = Record<string, unknown>;
116
+ interface ClientJobsResponse {
117
+ companyId: string;
118
+ lastSyncedAt: number;
119
+ buyer: Record<string, unknown>;
120
+ openJobs: Array<Record<string, unknown>>;
121
+ workHistory: Array<Record<string, unknown>>;
122
+ archivedCiphers: string[];
123
+ archivedJobIds: string[];
124
+ }
125
+ interface UpHuntOptions {
126
+ /** Your UpHunt API key. Falls back to `process.env.UPHUNT_API_KEY`. */
127
+ apiKey?: string;
128
+ /** API base URL. Defaults to `https://uphunt.io`. */
129
+ baseUrl?: string;
130
+ /** Custom fetch implementation (defaults to global `fetch`; Node 18+). */
131
+ fetch?: typeof fetch;
132
+ }
133
+ /** Thrown for any non-2xx API response. */
134
+ declare class UpHuntError extends Error {
135
+ readonly status: number;
136
+ readonly body: unknown;
137
+ constructor(message: string, status: number, body: unknown);
138
+ }
139
+ declare class UpHunt {
140
+ private readonly apiKey;
141
+ private readonly baseUrl;
142
+ private readonly fetchImpl;
143
+ constructor(options?: UpHuntOptions);
144
+ private request;
145
+ /** Queue a proposal submission. One credit is deducted on success. */
146
+ apply(input: ApplyInput): Promise<ApplyResponse>;
147
+ /** Poll an application's status by `queueId` or `jobId`. */
148
+ status(params: {
149
+ queueId?: string;
150
+ jobId?: string;
151
+ }): Promise<StatusResponse>;
152
+ /** Paginated list of jobs you've applied to. */
153
+ appliedJobs(params?: AppliedJobsParams): Promise<AppliedJobsResponse>;
154
+ /** Generate an AI cover letter for a job. */
155
+ generateProposal(input: GenerateProposalInput): Promise<GenerateProposalResponse>;
156
+ /** List the freelancers in your agency and their profiles. */
157
+ freelancers(): Promise<FreelancersResponse>;
158
+ /** Fetch a single archived Upwork job by its ciphertext (`~02…`). */
159
+ getJob(ciphertext: string): Promise<Job>;
160
+ /** Fetch a buyer's open jobs and work history by Upwork companyId. */
161
+ getClientJobs(companyId: string): Promise<ClientJobsResponse>;
162
+ }
163
+
164
+ export { type ApplicationStatus, type AppliedJob, type AppliedJobsParams, type AppliedJobsResponse, type ApplyInput, type ApplyResponse, type ClientJobsResponse, type Freelancer, type FreelancerProfile, type FreelancersResponse, type GenerateProposalInput, type GenerateProposalResponse, type Job, type Proposal, type QuestionAnswer, type ReasoningEffort, type StatusResponse, type Timeline, UpHunt, UpHuntError, type UpHuntOptions, UpHunt as default };
package/dist/index.js ADDED
@@ -0,0 +1,107 @@
1
+ // src/index.ts
2
+ var UpHuntError = class extends Error {
3
+ status;
4
+ body;
5
+ constructor(message, status, body) {
6
+ super(message);
7
+ this.name = "UpHuntError";
8
+ this.status = status;
9
+ this.body = body;
10
+ }
11
+ };
12
+ function envApiKey() {
13
+ return typeof process !== "undefined" ? process.env?.UPHUNT_API_KEY : void 0;
14
+ }
15
+ var UpHunt = class {
16
+ apiKey;
17
+ baseUrl;
18
+ fetchImpl;
19
+ constructor(options = {}) {
20
+ const apiKey = options.apiKey ?? envApiKey();
21
+ if (!apiKey) {
22
+ throw new Error(
23
+ "UpHunt: missing API key. Pass `new UpHunt({ apiKey })` or set UPHUNT_API_KEY."
24
+ );
25
+ }
26
+ this.apiKey = apiKey;
27
+ this.baseUrl = (options.baseUrl ?? "https://uphunt.io").replace(/\/+$/, "");
28
+ const f = options.fetch ?? globalThis.fetch;
29
+ if (!f) {
30
+ throw new Error("UpHunt: no global fetch found. Use Node 18+ or pass `{ fetch }`.");
31
+ }
32
+ this.fetchImpl = f;
33
+ }
34
+ async request(method, path, opts = {}) {
35
+ const url = new URL(this.baseUrl + path);
36
+ if (opts.query) {
37
+ for (const [k, v] of Object.entries(opts.query)) {
38
+ if (v !== void 0) url.searchParams.set(k, String(v));
39
+ }
40
+ }
41
+ const headers = { "x-api-key": this.apiKey };
42
+ if (opts.body !== void 0) headers["content-type"] = "application/json";
43
+ const res = await this.fetchImpl(url, {
44
+ method,
45
+ headers,
46
+ body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0
47
+ });
48
+ const text = await res.text();
49
+ let data;
50
+ try {
51
+ data = text ? JSON.parse(text) : void 0;
52
+ } catch {
53
+ data = text;
54
+ }
55
+ if (!res.ok) {
56
+ const message = data && typeof data === "object" && "error" in data ? String(data.error) : res.statusText || `HTTP ${res.status}`;
57
+ throw new UpHuntError(message, res.status, data);
58
+ }
59
+ return data;
60
+ }
61
+ /** Queue a proposal submission. One credit is deducted on success. */
62
+ apply(input) {
63
+ return this.request("POST", "/api/auto-apply-v2/apply", { body: input });
64
+ }
65
+ /** Poll an application's status by `queueId` or `jobId`. */
66
+ status(params) {
67
+ return this.request("GET", "/api/auto-apply-v2/status", {
68
+ query: params
69
+ });
70
+ }
71
+ /** Paginated list of jobs you've applied to. */
72
+ appliedJobs(params = {}) {
73
+ return this.request("GET", "/api/auto-apply-v2/applied-jobs", {
74
+ query: params
75
+ });
76
+ }
77
+ /** Generate an AI cover letter for a job. */
78
+ generateProposal(input) {
79
+ return this.request(
80
+ "POST",
81
+ "/api/auto-apply-v2/generate-proposal",
82
+ { body: input }
83
+ );
84
+ }
85
+ /** List the freelancers in your agency and their profiles. */
86
+ freelancers() {
87
+ return this.request("GET", "/api/auto-apply-v2/freelancers");
88
+ }
89
+ /** Fetch a single archived Upwork job by its ciphertext (`~02…`). */
90
+ getJob(ciphertext) {
91
+ return this.request("GET", "/api/jobs/by-ciphertext", { query: { cipher: ciphertext } });
92
+ }
93
+ /** Fetch a buyer's open jobs and work history by Upwork companyId. */
94
+ getClientJobs(companyId) {
95
+ return this.request(
96
+ "GET",
97
+ `/api/clients/${encodeURIComponent(companyId)}/jobs`
98
+ );
99
+ }
100
+ };
101
+ var index_default = UpHunt;
102
+ export {
103
+ UpHunt,
104
+ UpHuntError,
105
+ index_default as default
106
+ };
107
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Official UpHunt SDK for Node.js & TypeScript.\n *\n * Docs: https://uphunt.io/docs\n *\n * ```ts\n * import { UpHunt } from 'uphunt'\n * const uphunt = new UpHunt({ apiKey: process.env.UPHUNT_API_KEY })\n * const { queueId } = await uphunt.apply({ jobId: '~01abc', coverLetter: 'Hi…' })\n * ```\n */\n\nexport type Timeline =\n | 'Less than 1 month'\n | '1 to 3 months'\n | '3 to 6 months'\n | 'More than 6 months'\n\nexport type ReasoningEffort = 'low' | 'medium' | 'high'\n\nexport type ApplicationStatus =\n | 'processing'\n | 'applied'\n | 'failed'\n | 'not_available'\n | 'not_eligible'\n | 'not_enough_connects'\n | 'logged_out'\n\nexport interface Proposal {\n /** USD hourly bid (hourly jobs only). */\n hourlyRate?: number\n /** USD fixed bid (fixed-price jobs only). */\n fixedBid?: number\n timeline?: Timeline\n /** Extra Connects to boost the proposal's visibility. */\n boostBids?: number\n}\n\nexport interface QuestionAnswer {\n /** 0-indexed position from the job's `screeningQuestions`. */\n position: number\n answer: string\n}\n\nexport interface ApplyInput {\n /** Ciphertext (`~01abc…`), full Upwork URL, or processed job UUID. */\n jobId: string\n coverLetter: string\n /** Freelancer profileId from `freelancers()`. Defaults to the primary profile. */\n profileId?: string\n proposal?: Proposal\n /** AI-answer remaining screening questions. */\n autoFillOtherQuestions?: boolean\n /** Explicit answers for screening questions. */\n questionAnswers?: QuestionAnswer[]\n}\n\nexport interface ApplyResponse {\n success: boolean\n queueId: string\n creditsRemaining?: number\n message?: string\n}\n\nexport interface StatusResponse {\n jobId: string | null\n processedJobId: string | null\n applicationStatus: ApplicationStatus | null\n applicationStatusMessage: string | null\n queueId: string | null\n appliedAt: number | null\n processedAt: number | null\n errorMessage: string | null\n}\n\nexport interface AppliedJob {\n jobId: string | null\n processedJobId: string | null\n title: string | null\n url: string | null\n platform: 'upwork' | 'linkedin'\n applicationStatus: ApplicationStatus | null\n applicationStatusMessage: string | null\n matchingScore: number | null\n queueId: string | null\n appliedAt: number | null\n processedAt: number | null\n errorMessage: string | null\n coverLetter: string | null\n createdAt: number | null\n}\n\nexport interface AppliedJobsResponse {\n jobs: AppliedJob[]\n total: number\n limit: number\n offset: number\n}\n\nexport interface AppliedJobsParams {\n limit?: number\n offset?: number\n status?: ApplicationStatus\n}\n\nexport interface GenerateProposalInput {\n /** Ciphertext, URL, or processed job UUID. Required unless title+description given. */\n jobId?: string\n jobTitle?: string\n jobDescription?: string\n /** Job listener ID whose custom prompt should be used. */\n feedId?: string\n reasoningEffort?: ReasoningEffort\n}\n\nexport interface GenerateProposalResponse {\n success: boolean\n proposal: string\n}\n\nexport interface FreelancerProfile {\n type: 'default'\n name: string\n hourlyRate: number | null\n currency: string\n profileId: string\n}\n\nexport interface Freelancer {\n id: string\n name: string\n avatarUrl: string | null\n baseHourlyRate: number | null\n profiles: FreelancerProfile[]\n}\n\nexport interface FreelancersResponse {\n freelancers: Freelancer[]\n}\n\n/** Full archived RawUpworkJob document. Shape is open-ended; key fields typed loosely. */\nexport type Job = Record<string, unknown>\n\nexport interface ClientJobsResponse {\n companyId: string\n lastSyncedAt: number\n buyer: Record<string, unknown>\n openJobs: Array<Record<string, unknown>>\n workHistory: Array<Record<string, unknown>>\n archivedCiphers: string[]\n archivedJobIds: string[]\n}\n\nexport interface UpHuntOptions {\n /** Your UpHunt API key. Falls back to `process.env.UPHUNT_API_KEY`. */\n apiKey?: string\n /** API base URL. Defaults to `https://uphunt.io`. */\n baseUrl?: string\n /** Custom fetch implementation (defaults to global `fetch`; Node 18+). */\n fetch?: typeof fetch\n}\n\n/** Thrown for any non-2xx API response. */\nexport class UpHuntError extends Error {\n readonly status: number\n readonly body: unknown\n constructor(message: string, status: number, body: unknown) {\n super(message)\n this.name = 'UpHuntError'\n this.status = status\n this.body = body\n }\n}\n\ntype Query = Record<string, string | number | boolean | undefined>\n\nfunction envApiKey(): string | undefined {\n return typeof process !== 'undefined' ? process.env?.UPHUNT_API_KEY : undefined\n}\n\nexport class UpHunt {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly fetchImpl: typeof fetch\n\n constructor(options: UpHuntOptions = {}) {\n const apiKey = options.apiKey ?? envApiKey()\n if (!apiKey) {\n throw new Error(\n 'UpHunt: missing API key. Pass `new UpHunt({ apiKey })` or set UPHUNT_API_KEY.',\n )\n }\n this.apiKey = apiKey\n this.baseUrl = (options.baseUrl ?? 'https://uphunt.io').replace(/\\/+$/, '')\n const f = options.fetch ?? globalThis.fetch\n if (!f) {\n throw new Error('UpHunt: no global fetch found. Use Node 18+ or pass `{ fetch }`.')\n }\n this.fetchImpl = f\n }\n\n private async request<T>(\n method: 'GET' | 'POST',\n path: string,\n opts: { query?: Query; body?: unknown } = {},\n ): Promise<T> {\n const url = new URL(this.baseUrl + path)\n if (opts.query) {\n for (const [k, v] of Object.entries(opts.query)) {\n if (v !== undefined) url.searchParams.set(k, String(v))\n }\n }\n\n const headers: Record<string, string> = { 'x-api-key': this.apiKey }\n if (opts.body !== undefined) headers['content-type'] = 'application/json'\n\n const res = await this.fetchImpl(url, {\n method,\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n })\n\n const text = await res.text()\n let data: unknown\n try {\n data = text ? JSON.parse(text) : undefined\n } catch {\n data = text\n }\n\n if (!res.ok) {\n const message =\n data && typeof data === 'object' && 'error' in data\n ? String((data as { error: unknown }).error)\n : res.statusText || `HTTP ${res.status}`\n throw new UpHuntError(message, res.status, data)\n }\n\n return data as T\n }\n\n /** Queue a proposal submission. One credit is deducted on success. */\n apply(input: ApplyInput): Promise<ApplyResponse> {\n return this.request<ApplyResponse>('POST', '/api/auto-apply-v2/apply', { body: input })\n }\n\n /** Poll an application's status by `queueId` or `jobId`. */\n status(params: { queueId?: string; jobId?: string }): Promise<StatusResponse> {\n return this.request<StatusResponse>('GET', '/api/auto-apply-v2/status', {\n query: params as Query,\n })\n }\n\n /** Paginated list of jobs you've applied to. */\n appliedJobs(params: AppliedJobsParams = {}): Promise<AppliedJobsResponse> {\n return this.request<AppliedJobsResponse>('GET', '/api/auto-apply-v2/applied-jobs', {\n query: params as Query,\n })\n }\n\n /** Generate an AI cover letter for a job. */\n generateProposal(input: GenerateProposalInput): Promise<GenerateProposalResponse> {\n return this.request<GenerateProposalResponse>(\n 'POST',\n '/api/auto-apply-v2/generate-proposal',\n { body: input },\n )\n }\n\n /** List the freelancers in your agency and their profiles. */\n freelancers(): Promise<FreelancersResponse> {\n return this.request<FreelancersResponse>('GET', '/api/auto-apply-v2/freelancers')\n }\n\n /** Fetch a single archived Upwork job by its ciphertext (`~02…`). */\n getJob(ciphertext: string): Promise<Job> {\n return this.request<Job>('GET', '/api/jobs/by-ciphertext', { query: { cipher: ciphertext } })\n }\n\n /** Fetch a buyer's open jobs and work history by Upwork companyId. */\n getClientJobs(companyId: string): Promise<ClientJobsResponse> {\n return this.request<ClientJobsResponse>(\n 'GET',\n `/api/clients/${encodeURIComponent(companyId)}/jobs`,\n )\n }\n}\n\nexport default UpHunt\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "uphunt",
3
+ "version": "0.1.0",
4
+ "description": "Official UpHunt SDK — auto-apply to Upwork jobs, fetch archived job & client data, and generate AI proposals from Node.js & TypeScript.",
5
+ "keywords": [
6
+ "uphunt",
7
+ "upwork",
8
+ "upwork-api",
9
+ "auto-apply",
10
+ "freelance",
11
+ "proposals",
12
+ "job-application",
13
+ "sdk",
14
+ "api-client"
15
+ ],
16
+ "license": "MIT",
17
+ "author": "UpHunt",
18
+ "homepage": "https://uphunt.io/docs",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/ffucucuoglu/uphunt-node.git"
22
+ },
23
+ "bugs": {
24
+ "url": "https://uphunt.io/docs"
25
+ },
26
+ "type": "module",
27
+ "main": "./dist/index.cjs",
28
+ "module": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "import": "./dist/index.js",
34
+ "require": "./dist/index.cjs"
35
+ }
36
+ },
37
+ "files": [
38
+ "dist",
39
+ "README.md",
40
+ "LICENSE"
41
+ ],
42
+ "engines": {
43
+ "node": ">=18"
44
+ },
45
+ "sideEffects": false,
46
+ "scripts": {
47
+ "build": "tsup src/index.ts --format esm,cjs --dts --clean --sourcemap",
48
+ "typecheck": "tsc --noEmit",
49
+ "prepublishOnly": "npm run build"
50
+ },
51
+ "devDependencies": {
52
+ "tsup": "^8.3.5",
53
+ "typescript": "^5.6.3"
54
+ }
55
+ }