# Freelance Proposal Writer (short, human, priced) (`danielmichalek/freelance-proposal-writer`) Actor

Turns freelance job posts from any platform into short, human-sounding proposals with a GO/MAYBE/SKIP verdict, a price inside your rate card and a delivery time. Works without an API key; optional LLM polishing with your own key.

- **URL**: https://apify.com/danielmichalek/freelance-proposal-writer.md
- **Developed by:** [Daniel Michałek](https://apify.com/danielmichalek) (community)
- **Categories:** AI, Jobs, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 proposal writtens

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Freelance Proposal Writer

Turn freelance job posts into **short proposals that read like a person wrote them**, with a clear **GO / MAYBE / SKIP** verdict, a **price inside your own rate card** and a **delivery time**. Paste jobs from Upwork, Freelancer.com, Fiverr briefs, PeoplePerHour, Useme or any other board, describe what you sell once, and get ready-to-send proposals in seconds.

It works out of the box **without any API key** (a deterministic writer built for short, plain, human proposals). If you want more natural wording, plug in **your own** OpenAI-compatible LLM key (OpenAI, OpenRouter, Groq, a local Ollama) and every LLM draft still has to pass the same quality checks.

### What it does

1. **Reads each job**: budget (ranges, currencies, hourly), deadline (also "ASAP", "within two weeks", Polish and German phrases), tools and numbers mentioned in the post.
2. **Qualifies it** against your services: keyword match, your exclusions and hard red flags (adult, gambling, fake reviews, academic cheating, account trading, hacking, full-time employment, on-site work, phone work, regulated advice, "no AI" posts, location-restricted posts, deadlines shorter than your minimum).
3. **Prices it** inside your rate card and the client's budget, rounds like a human ($140, not $137.50) and never quotes less than your minimum delivery time (7 days by default).
4. **Writes a two-paragraph proposal** in the language of the post (English, Polish or German): one concrete detail from the post, your first step, what the client gets, price and days, one honest line about using AI tools (optional) and one closing question.
5. **Checks quality** before output: max length, no dashes or lists, no emoji, no "I hope this finds you well", no "leverage / seamless / delve", no invented years of experience, client counts, ratings or guarantees, exact price and days present, one question at most two.

### Input

| Field | What it is |
|---|---|
| `jobs` | Array of job posts: `title`, `description`, `budget` (for example `"$150 - $250 USD"`, `"500 zł"`) or `budgetMin` / `budgetMax` / `currency`, optional `skills`, `deadlineDays`, `url`, `id`, `platform`, `language`. Up to 500 per run. |
| `profile` | Your name, signature, a short `about` and your `services` (keywords, exclusions, price range, currency, days, rights, first step, deliverables, what you need from the client, optional sample link). Text fields can be plain strings or `{ "en": ..., "pl": ..., "de": ... }`. |
| `language` | `auto` (the language of each post) or force `en` / `pl` / `de`. |
| `maxChars` | Maximum proposal length, default 900 characters. |
| `minDays` | Minimum delivery time and minimum job deadline, default 7 days. |
| `discloseAi` | Adds one plain sentence that you work with AI tools and check results by hand (default on). |
| `excludeKeywords` | Your own words to skip. |
| `llmBaseUrl`, `llmModel`, `llmApiKey` | Optional LLM polishing with your key (stored encrypted, never logged). |

Leave `jobs` and `profile` empty to try the built-in example.

### Output

One dataset item per job:

```json
{
  "verdict": "GO",
  "title": "Merge and clean two customer CSV files",
  "proposal": "Hi, I can take this on. ...\n\nI can do it for 200 USD in 7 days. ...",
  "priceAmount": 200, "priceCurrency": "USD", "deliveryDays": 7,
  "service": "Spreadsheet cleanup and merging",
  "reasons": [], "warnings": [], "specifics": ["2,000 rows", "CSV", "Excel"],
  "mode": "template", "qualityChecks": { "pass": true, "violations": [] }
}
```

`OUTPUT` in the key-value store holds the run summary (jobs, GO / MAYBE / SKIP counts, proposals, charged events).

### Pricing

Pay per event: you pay only for **proposals actually written** (`proposal-written`). Skipped jobs and jobs without a proposal are free. LLM usage, if you enable it, is billed by your own provider.

### Honest by design

The writer only states facts from your profile. It never invents experience, clients, reviews, certificates or guarantees, and it skips posts that forbid AI. You stay in control of what you send: this Actor writes proposals, it does not log in to any platform or submit anything on your behalf.

# Actor input Schema

## `jobs` (type: `array`):

Job posts from any platform. Each item: { "title", "description", "budget" (text like "$150 - $250 USD" or "500 zł", or budgetMin/budgetMax/currency), "skills" (optional list), "deadlineDays" (optional), "url", "id", "platform", "language" (optional en/pl/de) }. Up to 500 per run. Leave both jobs and profile empty to run the free built-in demo.

## `profile` (type: `object`):

Who you are and what you sell. { "name", "signature", "about", "discloseAi", "services": \[{ "id", "name", "keywords" \[...], "excludes" \[...], "priceFrom", "priceTo", "currency", "daysFrom", "daysTo", "rights" (TRANSFER or NONE), "firstStep", "deliverables", "inputsNeeded", "sampleUrl" }] }. Text fields can be a string or { "en", "pl", "de" }. Proposals only use facts from here: no invented experience, clients or guarantees.

## `language` (type: `string`):

auto = the language of each job post.

## `maxChars` (type: `integer`):

Short proposals get read. 900 characters is about 120 to 150 words.

## `minDays` (type: `integer`):

Jobs whose deadline is shorter (or marked urgent / ASAP) are skipped, and your quoted delivery time is never shorter than this.

## `discloseAi` (type: `boolean`):

Adds one plain sentence that you use AI tools and check the results by hand. Honest and increasingly expected by clients.

## `includeSamples` (type: `boolean`):

Adds the service sampleUrl when there is room.

## `writeMaybe` (type: `boolean`):

MAYBE = matched but with a soft warning (for example a service limit). SKIP jobs never get a proposal.

## `includeSkipped` (type: `boolean`):

Keeps the verdict and reasons for every job, also when no proposal was written.

## `excludeKeywords` (type: `array`):

Jobs containing any of these words are skipped (case and accents ignored).

## `llmBaseUrl` (type: `string`):

Any OpenAI-compatible endpoint, for example https://api.openai.com/v1 or https://openrouter.ai/api/v1. Leave empty to use the built-in template writer (free, deterministic).

## `llmModel` (type: `string`):

For example gpt-4o-mini or an OpenRouter model id.

## `llmApiKey` (type: `string`):

Stored encrypted by Apify, never logged or written to the output. LLM costs are billed by your provider.

## Actor input object example

```json
{
  "jobs": [
    {
      "id": "example-1",
      "platform": "freelancer.com",
      "url": "https://www.freelancer.com/projects/excel/example",
      "title": "Merge and clean two customer CSV files",
      "description": "We have two CSV exports (about 2,000 rows each) from our shop and CRM. Please merge them into one Excel file, remove duplicates by email and fix name capitalization. Delivery within 10 days.",
      "budget": "$150 - $250 USD",
      "skills": [
        "Excel",
        "Data Cleansing",
        "CSV"
      ]
    },
    {
      "id": "example-2",
      "platform": "useme",
      "url": "https://useme.com/pl/jobs/example,2/",
      "title": "Tłumaczenie instrukcji obsługi na angielski",
      "description": "Potrzebuję przetłumaczyć instrukcję obsługi urządzenia (12 stron, plik DOCX) z polskiego na angielski. Termin realizacji: 2 tygodnie.",
      "budget": "500 zł"
    },
    {
      "id": "example-3",
      "platform": "upwork",
      "url": "https://www.upwork.com/jobs/example-3",
      "title": "Full-time data entry clerk",
      "description": "Full-time position, 40 hours per week, monthly salary. Excel data entry.",
      "budget": "$400 - $600 USD"
    }
  ],
  "profile": {
    "name": "Alex",
    "signature": "Alex",
    "discloseAi": true,
    "about": "I clean and merge spreadsheet data, translate between English and Polish and edit short vertical videos.",
    "services": [
      {
        "id": "data",
        "name": "Spreadsheet cleanup and merging",
        "keywords": [
          "excel",
          "csv",
          "spreadsheet",
          "google sheets",
          "data cleaning",
          "deduplicate",
          "merge",
          "data entry"
        ],
        "excludes": [
          "vba",
          "power bi"
        ],
        "priceFrom": 80,
        "priceTo": 300,
        "currency": "USD",
        "daysFrom": 7,
        "daysTo": 7,
        "rights": "NONE",
        "firstStep": {
          "en": "a quick check of a sample of your file",
          "pl": "sprawdzenia próbki pliku"
        },
        "deliverables": {
          "en": [
            "the cleaned file in XLSX or CSV",
            "a short list of what was changed"
          ],
          "pl": [
            "uporządkowany plik XLSX albo CSV",
            "krótką listę zmian"
          ]
        },
        "inputsNeeded": {
          "en": [
            "a sample of the file"
          ],
          "pl": [
            "próbkę pliku"
          ]
        }
      },
      {
        "id": "translation",
        "name": "Translation English Polish",
        "keywords": [
          "translation",
          "translate",
          "tłumaczenie",
          "tlumaczenie",
          "przetłumaczyć",
          "proofreading",
          "polish",
          "korekta"
        ],
        "excludes": [
          "sworn",
          "przysięgł"
        ],
        "priceFrom": 200,
        "priceTo": 900,
        "currency": "PLN",
        "daysFrom": 7,
        "daysTo": 7,
        "rights": "TRANSFER",
        "firstStep": {
          "en": "a sample paragraph so you can check the tone",
          "pl": "próbnego akapitu do sprawdzenia stylu"
        },
        "firstStepNom": {
          "pl": "próbny akapit do sprawdzenia stylu"
        },
        "deliverables": {
          "en": [
            "the translated text in your file format"
          ],
          "pl": [
            "przetłumaczony tekst w tym samym formacie pliku"
          ]
        },
        "inputsNeeded": {
          "en": [
            "the text or file"
          ],
          "pl": [
            "tekst albo plik"
          ]
        }
      },
      {
        "id": "video",
        "name": "Short vertical video editing",
        "keywords": [
          "reels",
          "shorts",
          "tiktok",
          "video editing",
          "subtitles",
          "captions",
          "vertical video"
        ],
        "priceFrom": 60,
        "priceTo": 300,
        "currency": "USD",
        "daysFrom": 7,
        "daysTo": 10,
        "rights": "TRANSFER",
        "firstStep": {
          "en": "one test clip from your material"
        },
        "deliverables": {
          "en": [
            "the edited vertical videos in MP4 with captions"
          ]
        },
        "inputsNeeded": {
          "en": [
            "the raw clips or a link to them"
          ]
        }
      }
    ]
  },
  "language": "auto",
  "maxChars": 900,
  "minDays": 7,
  "discloseAi": true,
  "includeSamples": true,
  "writeMaybe": true,
  "includeSkipped": true,
  "excludeKeywords": []
}
```

# Actor output Schema

## `proposals` (type: `string`):

Dataset items in the Proposals view (verdict, job, price, days, proposal text, link).

## `summary` (type: `string`):

Counts of GO, MAYBE and SKIP jobs, proposals written and charged events.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "jobs": [
        {
            "id": "example-1",
            "platform": "freelancer.com",
            "url": "https://www.freelancer.com/projects/excel/example",
            "title": "Merge and clean two customer CSV files",
            "description": "We have two CSV exports (about 2,000 rows each) from our shop and CRM. Please merge them into one Excel file, remove duplicates by email and fix name capitalization. Delivery within 10 days.",
            "budget": "$150 - $250 USD",
            "skills": [
                "Excel",
                "Data Cleansing",
                "CSV"
            ]
        },
        {
            "id": "example-2",
            "platform": "useme",
            "url": "https://useme.com/pl/jobs/example,2/",
            "title": "Tłumaczenie instrukcji obsługi na angielski",
            "description": "Potrzebuję przetłumaczyć instrukcję obsługi urządzenia (12 stron, plik DOCX) z polskiego na angielski. Termin realizacji: 2 tygodnie.",
            "budget": "500 zł"
        },
        {
            "id": "example-3",
            "platform": "upwork",
            "url": "https://www.upwork.com/jobs/example-3",
            "title": "Full-time data entry clerk",
            "description": "Full-time position, 40 hours per week, monthly salary. Excel data entry.",
            "budget": "$400 - $600 USD"
        }
    ],
    "profile": {
        "name": "Alex",
        "signature": "Alex",
        "discloseAi": true,
        "about": "I clean and merge spreadsheet data, translate between English and Polish and edit short vertical videos.",
        "services": [
            {
                "id": "data",
                "name": "Spreadsheet cleanup and merging",
                "keywords": [
                    "excel",
                    "csv",
                    "spreadsheet",
                    "google sheets",
                    "data cleaning",
                    "deduplicate",
                    "merge",
                    "data entry"
                ],
                "excludes": [
                    "vba",
                    "power bi"
                ],
                "priceFrom": 80,
                "priceTo": 300,
                "currency": "USD",
                "daysFrom": 7,
                "daysTo": 7,
                "rights": "NONE",
                "firstStep": {
                    "en": "a quick check of a sample of your file",
                    "pl": "sprawdzenia próbki pliku"
                },
                "deliverables": {
                    "en": [
                        "the cleaned file in XLSX or CSV",
                        "a short list of what was changed"
                    ],
                    "pl": [
                        "uporządkowany plik XLSX albo CSV",
                        "krótką listę zmian"
                    ]
                },
                "inputsNeeded": {
                    "en": [
                        "a sample of the file"
                    ],
                    "pl": [
                        "próbkę pliku"
                    ]
                }
            },
            {
                "id": "translation",
                "name": "Translation English Polish",
                "keywords": [
                    "translation",
                    "translate",
                    "tłumaczenie",
                    "tlumaczenie",
                    "przetłumaczyć",
                    "proofreading",
                    "polish",
                    "korekta"
                ],
                "excludes": [
                    "sworn",
                    "przysięgł"
                ],
                "priceFrom": 200,
                "priceTo": 900,
                "currency": "PLN",
                "daysFrom": 7,
                "daysTo": 7,
                "rights": "TRANSFER",
                "firstStep": {
                    "en": "a sample paragraph so you can check the tone",
                    "pl": "próbnego akapitu do sprawdzenia stylu"
                },
                "firstStepNom": {
                    "pl": "próbny akapit do sprawdzenia stylu"
                },
                "deliverables": {
                    "en": [
                        "the translated text in your file format"
                    ],
                    "pl": [
                        "przetłumaczony tekst w tym samym formacie pliku"
                    ]
                },
                "inputsNeeded": {
                    "en": [
                        "the text or file"
                    ],
                    "pl": [
                        "tekst albo plik"
                    ]
                }
            },
            {
                "id": "video",
                "name": "Short vertical video editing",
                "keywords": [
                    "reels",
                    "shorts",
                    "tiktok",
                    "video editing",
                    "subtitles",
                    "captions",
                    "vertical video"
                ],
                "priceFrom": 60,
                "priceTo": 300,
                "currency": "USD",
                "daysFrom": 7,
                "daysTo": 10,
                "rights": "TRANSFER",
                "firstStep": {
                    "en": "one test clip from your material"
                },
                "deliverables": {
                    "en": [
                        "the edited vertical videos in MP4 with captions"
                    ]
                },
                "inputsNeeded": {
                    "en": [
                        "the raw clips or a link to them"
                    ]
                }
            }
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("danielmichalek/freelance-proposal-writer").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "jobs": [
        {
            "id": "example-1",
            "platform": "freelancer.com",
            "url": "https://www.freelancer.com/projects/excel/example",
            "title": "Merge and clean two customer CSV files",
            "description": "We have two CSV exports (about 2,000 rows each) from our shop and CRM. Please merge them into one Excel file, remove duplicates by email and fix name capitalization. Delivery within 10 days.",
            "budget": "$150 - $250 USD",
            "skills": [
                "Excel",
                "Data Cleansing",
                "CSV",
            ],
        },
        {
            "id": "example-2",
            "platform": "useme",
            "url": "https://useme.com/pl/jobs/example,2/",
            "title": "Tłumaczenie instrukcji obsługi na angielski",
            "description": "Potrzebuję przetłumaczyć instrukcję obsługi urządzenia (12 stron, plik DOCX) z polskiego na angielski. Termin realizacji: 2 tygodnie.",
            "budget": "500 zł",
        },
        {
            "id": "example-3",
            "platform": "upwork",
            "url": "https://www.upwork.com/jobs/example-3",
            "title": "Full-time data entry clerk",
            "description": "Full-time position, 40 hours per week, monthly salary. Excel data entry.",
            "budget": "$400 - $600 USD",
        },
    ],
    "profile": {
        "name": "Alex",
        "signature": "Alex",
        "discloseAi": True,
        "about": "I clean and merge spreadsheet data, translate between English and Polish and edit short vertical videos.",
        "services": [
            {
                "id": "data",
                "name": "Spreadsheet cleanup and merging",
                "keywords": [
                    "excel",
                    "csv",
                    "spreadsheet",
                    "google sheets",
                    "data cleaning",
                    "deduplicate",
                    "merge",
                    "data entry",
                ],
                "excludes": [
                    "vba",
                    "power bi",
                ],
                "priceFrom": 80,
                "priceTo": 300,
                "currency": "USD",
                "daysFrom": 7,
                "daysTo": 7,
                "rights": "NONE",
                "firstStep": {
                    "en": "a quick check of a sample of your file",
                    "pl": "sprawdzenia próbki pliku",
                },
                "deliverables": {
                    "en": [
                        "the cleaned file in XLSX or CSV",
                        "a short list of what was changed",
                    ],
                    "pl": [
                        "uporządkowany plik XLSX albo CSV",
                        "krótką listę zmian",
                    ],
                },
                "inputsNeeded": {
                    "en": ["a sample of the file"],
                    "pl": ["próbkę pliku"],
                },
            },
            {
                "id": "translation",
                "name": "Translation English Polish",
                "keywords": [
                    "translation",
                    "translate",
                    "tłumaczenie",
                    "tlumaczenie",
                    "przetłumaczyć",
                    "proofreading",
                    "polish",
                    "korekta",
                ],
                "excludes": [
                    "sworn",
                    "przysięgł",
                ],
                "priceFrom": 200,
                "priceTo": 900,
                "currency": "PLN",
                "daysFrom": 7,
                "daysTo": 7,
                "rights": "TRANSFER",
                "firstStep": {
                    "en": "a sample paragraph so you can check the tone",
                    "pl": "próbnego akapitu do sprawdzenia stylu",
                },
                "firstStepNom": { "pl": "próbny akapit do sprawdzenia stylu" },
                "deliverables": {
                    "en": ["the translated text in your file format"],
                    "pl": ["przetłumaczony tekst w tym samym formacie pliku"],
                },
                "inputsNeeded": {
                    "en": ["the text or file"],
                    "pl": ["tekst albo plik"],
                },
            },
            {
                "id": "video",
                "name": "Short vertical video editing",
                "keywords": [
                    "reels",
                    "shorts",
                    "tiktok",
                    "video editing",
                    "subtitles",
                    "captions",
                    "vertical video",
                ],
                "priceFrom": 60,
                "priceTo": 300,
                "currency": "USD",
                "daysFrom": 7,
                "daysTo": 10,
                "rights": "TRANSFER",
                "firstStep": { "en": "one test clip from your material" },
                "deliverables": { "en": ["the edited vertical videos in MP4 with captions"] },
                "inputsNeeded": { "en": ["the raw clips or a link to them"] },
            },
        ],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("danielmichalek/freelance-proposal-writer").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "jobs": [
    {
      "id": "example-1",
      "platform": "freelancer.com",
      "url": "https://www.freelancer.com/projects/excel/example",
      "title": "Merge and clean two customer CSV files",
      "description": "We have two CSV exports (about 2,000 rows each) from our shop and CRM. Please merge them into one Excel file, remove duplicates by email and fix name capitalization. Delivery within 10 days.",
      "budget": "$150 - $250 USD",
      "skills": [
        "Excel",
        "Data Cleansing",
        "CSV"
      ]
    },
    {
      "id": "example-2",
      "platform": "useme",
      "url": "https://useme.com/pl/jobs/example,2/",
      "title": "Tłumaczenie instrukcji obsługi na angielski",
      "description": "Potrzebuję przetłumaczyć instrukcję obsługi urządzenia (12 stron, plik DOCX) z polskiego na angielski. Termin realizacji: 2 tygodnie.",
      "budget": "500 zł"
    },
    {
      "id": "example-3",
      "platform": "upwork",
      "url": "https://www.upwork.com/jobs/example-3",
      "title": "Full-time data entry clerk",
      "description": "Full-time position, 40 hours per week, monthly salary. Excel data entry.",
      "budget": "$400 - $600 USD"
    }
  ],
  "profile": {
    "name": "Alex",
    "signature": "Alex",
    "discloseAi": true,
    "about": "I clean and merge spreadsheet data, translate between English and Polish and edit short vertical videos.",
    "services": [
      {
        "id": "data",
        "name": "Spreadsheet cleanup and merging",
        "keywords": [
          "excel",
          "csv",
          "spreadsheet",
          "google sheets",
          "data cleaning",
          "deduplicate",
          "merge",
          "data entry"
        ],
        "excludes": [
          "vba",
          "power bi"
        ],
        "priceFrom": 80,
        "priceTo": 300,
        "currency": "USD",
        "daysFrom": 7,
        "daysTo": 7,
        "rights": "NONE",
        "firstStep": {
          "en": "a quick check of a sample of your file",
          "pl": "sprawdzenia próbki pliku"
        },
        "deliverables": {
          "en": [
            "the cleaned file in XLSX or CSV",
            "a short list of what was changed"
          ],
          "pl": [
            "uporządkowany plik XLSX albo CSV",
            "krótką listę zmian"
          ]
        },
        "inputsNeeded": {
          "en": [
            "a sample of the file"
          ],
          "pl": [
            "próbkę pliku"
          ]
        }
      },
      {
        "id": "translation",
        "name": "Translation English Polish",
        "keywords": [
          "translation",
          "translate",
          "tłumaczenie",
          "tlumaczenie",
          "przetłumaczyć",
          "proofreading",
          "polish",
          "korekta"
        ],
        "excludes": [
          "sworn",
          "przysięgł"
        ],
        "priceFrom": 200,
        "priceTo": 900,
        "currency": "PLN",
        "daysFrom": 7,
        "daysTo": 7,
        "rights": "TRANSFER",
        "firstStep": {
          "en": "a sample paragraph so you can check the tone",
          "pl": "próbnego akapitu do sprawdzenia stylu"
        },
        "firstStepNom": {
          "pl": "próbny akapit do sprawdzenia stylu"
        },
        "deliverables": {
          "en": [
            "the translated text in your file format"
          ],
          "pl": [
            "przetłumaczony tekst w tym samym formacie pliku"
          ]
        },
        "inputsNeeded": {
          "en": [
            "the text or file"
          ],
          "pl": [
            "tekst albo plik"
          ]
        }
      },
      {
        "id": "video",
        "name": "Short vertical video editing",
        "keywords": [
          "reels",
          "shorts",
          "tiktok",
          "video editing",
          "subtitles",
          "captions",
          "vertical video"
        ],
        "priceFrom": 60,
        "priceTo": 300,
        "currency": "USD",
        "daysFrom": 7,
        "daysTo": 10,
        "rights": "TRANSFER",
        "firstStep": {
          "en": "one test clip from your material"
        },
        "deliverables": {
          "en": [
            "the edited vertical videos in MP4 with captions"
          ]
        },
        "inputsNeeded": {
          "en": [
            "the raw clips or a link to them"
          ]
        }
      }
    ]
  }
}' |
apify call danielmichalek/freelance-proposal-writer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,danielmichalek/freelance-proposal-writer"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/cn6nI9YiSy5pJfH2H/builds/PWaKUwLlsAC4gcaI9/openapi.json
