- Brand
- Contra
- Category
- Operations
- Primary Subcategory
- Talent Marketplaces & Freelance Hiring
Integration details
Description
Contra helps businesses, hiring teams, freelancers and studios manage freelance hiring and work from ChatGPT. Find freelancers and studios, compare their portfolios and reviews, and contact candidates. Hiring teams can create and update job posts, review applicants, shortlist or dismiss candidates, and send replies. Freelancers can find opportunities, save jobs, prepare applications, and create or update portfolio projects. Use your connected Contra account to read and send messages and choose among workspaces you can access. Portfolio changes, inquiries, messages, job changes and applications show a preview and require your approval before confirmation. Candidate and saved-job actions follow your explicit request. Freelancer searches record inferred role, tool and industry interests used to personalize your Contra feed. Adding collaborators to portfolio projects sends invitation emails, and existing Contra users also receive notifications. These invitations cannot be recalled and require approval before confirmation. Requires a Contra account, authorization to connect it, and the relevant workspace permissions. Results and job publication remain subject to Contra eligibility and moderation. Invoice payments, direct payments, product purchases, admin account provisioning and whole-website portfolio imports are unsupported.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Talent Marketplaces & Freelance Hiring
- Secondary Subcategories
- None listed
- Brand
- Contra
- Access
- Account required
- First tracked
- 2026-11-12
- Tool count
- 44
- Market
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Not discoverable in ChatGPT yet
ChatGPT now suggests Plugins on its own when they match a user's request, but not every Plugin is being surfaced yet.We haven’t seen Contra suggested yet. Sign up and we’ll track it, and your Discoverability Score will appear here once ChatGPT starts surfacing it.
What discovery looks like

Get alerts for Contra
Get updates when Contra’s Discoverability Score or category rank changes.
Competing in ChatGPT Talent Marketplaces & Freelance Hiring
View Category44 tools agents can invoke
Submits a prepared job application draft by ID via applyForJobPosting. Only call this after the user has explicitly approved the preview from apply_to_job_prepare.
Prepares an application to a public Contra job posting and returns a draft preview. This is how freelancers apply to jobs they found via list_job_feed or get_job_by_slug. **Apply to Job Workflow — guide the user naturally through these steps:** **Step 1 · Identify the job posting.** If the user has not already picked a specific job, use `list_job_feed` (or `get_job_by_slug`) to find candidates first and show visible options. You need the `jobPostingId` (not the `jobId`) returned by those tools to apply. **Step 2 · Fit gate.** Before preparing any application, compare the job's required skills/tools with the user's stated skills and portfolio projects. If the fit is weak, warn once with specifics. For batch/mass-apply requests, skip weak matches unconditionally and state why. **Step 3 · Draft the application message.** If the user gave explicit apply/send intent, draft from the job, profile, portfolio, and thread context immediately using stated assumptions for gaps. Do not ask another form. The message should be plain text, personalized to the posting, and highlight why the user is a strong fit. Keep it under 10,000 characters. **Step 4 · Attach portfolio by default.** Call `list_portfolio_projects` for the applying freelancer and pass relevant project `id` values in `relatedPortfolioProjectIds`. If no project is relevant, say that. Preparing without attachments requires the user to explicitly opt out in this conversation; only then set `portfolioAttachmentOptOutConfirmed: true`. Once all information is gathered, call this tool to prepare the draft. Show the returned preview to the user and wait for explicit approval before calling `apply_to_job_confirm`.
Returns the current MCP auth context (cookie/bearer) that will be used for GraphQL calls.
Save a Contra job board opportunity so the user can revisit it later from the Bookmarked tab. Use when the user says things like 'bookmark this', 'save this job', 'add to my saved jobs', or 'I want to look at this later'. The affected job moves into the BOOKMARKED preset of list_job_feed. This action is reversible — use remove_job_bookmark to undo.
Executes a prepared standalone job creation draft by ID. The tool switches to the client workspace when needed and only posts the job publicly when publish was requested in create_job_prepare.
Prepares a new standalone job and returns a preview of the hiring workspace that will create it. Uses the active unified workspace or the legacy client workspace when no workspaceId is provided. **Job Creation Workflow — guide the user naturally through these steps:** **Step 1 · What are you hiring for?** Ask what role or outcome the user wants to hire for. From their description, gather the core job details: `title`, `roles`, `tools`, and a plain-text `description` that is at least 250 characters long. These should be human-readable Contra role/tool names or close search terms, not raw IDs. If the match is unclear, ask a follow-up instead of guessing. Also ask whether they want to include an optional `outcomeId`. **Step 2 · What is the budget and timeline?** Ask whether the job is fixed-price or rate-based. Use the exact budget type enums `FIXED_PRICE` or `RATE`. For rate-based budgets, use a budget interval enum of `DAY`, `HOUR`, `MONTH`, `TWO_WEEK`, `WEEK`, or `YEAR`. Also gather the budget range, whether there is an expected duration, the start timeframe using `IMMEDIATELY`, `SOON`, or `LATER`, and how many openings they want to hire for. **Step 3 · Who should be eligible?** Ask whether the job should be limited by country, timezone overlap, language requirements, or an expert-program restriction. Only gather these fields when they matter for the role. **Step 4 · Should the job stay private or go public?** Jobs are private by default. Ask whether the user wants the job to be public. Only set `publish: true` when they explicitly want that. If they want a public job with an external application link, also gather `externalUrl`. **Step 5 · Anything else?** Ask whether they want to add any optional details that have not been covered yet before preparing the draft. Once all information is gathered, call this tool to prepare the draft. Preparation selects the legacy hiring workspace when needed. Show the returned preview to the user and wait for explicit approval before calling `create_job_confirm`, which uses the previewed workspace. If they do not have a hiring workspace, the tool will return an error.
Confirms and creates a portfolio project from a draft prepared by create_portfolio_project_prepare. Publishes the project unless it was prepared as an unpublished draft. Adding collaborators sends collaboration invitation emails, and existing Contra users also receive notifications. These invitations cannot be recalled. Requires a draftId, confirm: true, and explicit user approval of the preview and collaborator invitations.
Prepares a new portfolio project for creation on your Contra profile and returns a draft preview. Inline images in markdown content () are automatically uploaded during prepare. Standalone Vimeo and YouTube URLs placed on their own line are embedded inline in the project body. All image URLs must be publicly accessible — local file paths and base64 are not supported. **Portfolio Project Creation Workflow — guide the user naturally through these steps:** **Step 1 · Project title.** Ask for the project title (max 64 chars). **Step 2 · Project content.** Ask for the project description/content. Supports markdown or plain text. To embed an inline video, place a supported provider URL on its own line; supported providers are Vimeo and YouTube (including youtu.be links, Shorts, and live video URLs). **Step 3 · Integrity check.** Never invent performance metrics, client names, project dates, reviews, earnings, or quantified outcomes. Spec, concept, or fictional work must be labeled as spec/concept in the title or content. Refuse to publish fictional work presented as client work. **Step 4 · Cover image.** Ask for a cover image URL. Must be a publicly accessible http/https URL. This is required when publishing immediately, but optional when creating as a draft (`draft: true`). Drafts without a cover image can add one later via `update_portfolio_project_prepare` before publishing. **Step 5 · Roles.** Ask for the roles performed on this project (1–3 roles, max 48 characters each). **Step 6 · Tools used.** Ask for the tools used on this project (1–5 tools, max 48 characters each). **Step 7 · Optional details.** Ask if the user wants to add collaborators, organizations, industries, project dates (start/end), or an external link. Explain that confirming a project with collaborators sends collaboration invitation emails, and existing Contra users also receive notifications. These invitations cannot be recalled. For organizations, each entry must be `{ name, url }` — the API requires a real public http/https URL for every organization (e.g. `{ name: "Contra", url: "https://contra.com" }`). If the user cannot provide a URL for an organization, do NOT add it; ask them to skip it instead. **Step 8 · Publish state.** Ask whether to publish the project immediately or save it as a draft. Map the answer to the `draft` field: `draft: false` (or omit) publishes immediately; `draft: true` saves as an unpublished draft hidden from the public portfolio. Drafts can be published later via `update_portfolio_project_prepare` with `draft: false`. Once all information is gathered, call this tool to prepare the draft. **MANDATORY preview display — before calling `create_portfolio_project_confirm`, you MUST show the user every row from the returned `preview.summary` array so they have full understanding of what will be created.** Each row is a `{ label, value }` pair already formatted for humans in plain language. Present them as a simple list, preserving the order, using the `label` text verbatim. Do NOT invent your own field names, do NOT use camelCase identifiers, do NOT skip rows whose value reads as "None" / "Not specified" — those empty values are intentional and help the user confirm that no data is missing. Only call `create_portfolio_project_confirm` after the user has explicitly approved this summary.
Mark a candidate as not a fit and remove them from active consideration. Use when the user says 'not a fit', 'pass on this one', 'reject', 'decline', 'not interested', 'thumbs down', or 'skip'. Dismissing a previously shortlisted candidate automatically removes the shortlist. This action is reversible — use undismiss_candidate to bring them back.
Dismiss a Contra job board opportunity and signal to Contra that it was not a fit. Use when the user says 'not a fit', 'hide this job', 'pass on this one', or 'don't show me this again'. The job moves into the NOT_A_FIT preset of list_job_feed and stops appearing in FOR_YOU. Optionally pass a short reason (e.g. 'budget too low') to improve future recommendations.
Fetches a job (scoped opportunity) by its public slug, returning title, status, description, budget, duration, posting state, organization, owner profile, and a `publicUrl` for linking the user to the listing. This tool expects only the slug value, not a full URL. Use the returned jobId when referencing this job in send_inquiry_prepare. Always use `publicUrl` when sharing a link to the job with the user — do not construct URLs manually.
Fetches full details for a single case-study portfolio project by its slug. Returns all project information including content, roles, tools, collaborators, and cover image. If the slug belongs to a profile social post, this tool returns a routing message instead of treating it like a case study.
Fetches a user profile by username, including the UserProfile ID needed for chat and inquiry flows, formal portfolio project previews, social-post-backed Work-tab items, and recent profile posts. Useful when the target user is not discoverable via search_freelancers. Profile work content has three distinct buckets. `projectPreviews` are formal portfolio projects/case studies: they live at `/p/{slug}`, have portfolio-project fields such as cover, title, roles, tools, outcomes, collaborators, and richer case-study content, and can be inspected or edited with the portfolio project tools. `workPostPreviews` are social-post-backed items that appear on the profile Work tab: they are posts surfaced as work, live at `/community/{socialPost.slug}`, usually contain shorter post-style text/media. They are valuable posts, contribute to the users public perception and work credibility, and simply showcase work in a less formal format than portfolio projects/case studies. Use them as Work-tab context, but do not pass their slugs to portfolio-project edit/detail tools. `postPreviews` are recent profile Posts-tab feed items from `socialPosts(filter: { username })`: they may include general updates, work notes, replies, or community content. They are useful profile context, but they are not portfolio projects unless separately represented in `projectPreviews`. When a user asks about portfolio projects, case studies, or related work for service attachments, prefer `projectPreviews` or `list_portfolio_projects` and `workPostPreviews` together. When a user asks about posts or Work-tab posts, include `workPostPreviews` and `postPreviews` and route them to the returned `/community/...` URLs. **Viewing images**: This tool returns `previewUrl` links for avatar, project cover, work-post, and profile-post images.
Lists chat conversations for the current authenticated user in the selected workspace, including participants, unread counts, and latest message previews. Accepts an optional workspaceId override for a specific available workspace.
Lists messages for a chat conversation for the current authenticated user. Accepts an optional workspaceId override for a specific available workspace.
List candidates (applicants and invited freelancers) for a specific job from the user's client workspace. Use list_jobs first to get the jobId if the user does not already know it. Supports filtering by status (e.g., show only shortlisted candidates), candidate type (applied vs. invited), and candidate source (verified Contra users, guests, or Contra picks). Results can be sorted by application date or relevance.
Browse and search the Contra job board (contra.com/jobs) as a freelancer. Returns paginated opportunities along with the visitor's relationship to each one (applied, bookmarked, dismissed, matched). Use this tool whenever the user asks to find jobs, browse opportunities, look for freelance work, or check bookmarked/applied jobs on Contra. For requests to find work on Contra, search using the user's message and profile context. Search broadly from the user's message/profile context, show visible results with links and budget when available, and offer one free high-leverage next action such as improving the profile, drafting a case study, or preparing an application for a visible job. Pick the appropriate preset based on the user's intent: - FOR_YOU — personalized, ranked matches (the default "For You" tab on contra.com/jobs) - ALL — every open opportunity the user can see - APPLIED — jobs the user has already applied to - BOOKMARKED — jobs the user saved - NOT_A_FIT — jobs the user dismissed - CLOSED — jobs that are no longer accepting applications Each returned entry includes a `jobId`, a `publicUrl` for linking the user to the listing, and, when the job is posted publicly, a `jobPosting.jobPostingId`. Pass the `jobPostingId` to `apply_to_job_prepare` to apply, or the `jobId` to `bookmark_job`, `remove_job_bookmark`, or `dismiss_job_feed_entry`. Always use `publicUrl` when sharing a link to the job with the user — do not construct URLs manually. **Access limits:** Users without a Contra Pro subscription see a limited subset of jobs (matched jobs plus a small preview of recent opportunities). When `accessLimitedFeed` is `true` in the response, results may not reflect the full Contra job board. If results are empty or sparse, check the `accessLimitGuidance` field for recommended messaging. Never lead with the Pro upsell, never state inaccessible-job counts, and mention Pro at most once only after free value has been delivered.
Lists existing jobs from the user's selected workspace, or from a specific available workspace when workspaceId is provided, so the MCP client can discover the correct jobId before managing a job. Use this tool first when the user wants to update, post, or unpost an existing job and does not already know the jobId. The returned jobId should then be passed to update_job_prepare, post_job_prepare, or unpost_job_prepare.
Fetches a freelancer's portfolio Work-tab content, split into case-study portfolio projects and social-post-backed work posts. `projects` contains case-study portfolio projects with full detail: id, slug, publishedAt, isDraft, content, roles, tools, outcomes, industries, organizations, collaborators, dates, external links, and verification status. `workPosts` contains profile work items backed by social posts; these live at `/community/{socialPost.slug}` and should not be passed to portfolio-project edit/detail tools. `totalCount` reports the raw Work-tab portfolio connection count for the selected visibility, including social-post-backed work posts and items outside the current page; `projects.length` only counts case-study items returned on this page. **Portfolio Project Listing Workflow — gather details in this order:** **Step 1 · Identify the profile.** Use the Contra username to fetch projects. When coming from search results, pass the user's `displayUsername` as `username`. **Step 2 · Choose visibility scope.** Omit `includeDrafts` or set it to `false` for normal public-discovery results. Set `includeDrafts: true` when the user asks about unpublished, hidden, or draft projects, such as "publish my drafts" or "remove this from my profile without deleting it". **Step 3 · Inspect publish state and content type.** Each returned case-study project includes `publishedAt` and `isDraft`. Draft projects have `publishedAt: null` and `isDraft: true`; published projects have a timestamp and `isDraft: false`. Social-post-backed work items are returned separately in `workPosts` with `socialPost.url` routing data. Use this after `search_freelancers` or `get_user_profile_by_username` to evaluate whether a freelancer's past work matches what the client is looking for. This tool is part of the Talent Discovery Workflow described in `search_freelancers` — use it during the deep-dive phase to assess project relevance, tools match, and outcome quality for shortlisted candidates. The returned `id` on each project is also the canonical identifier to pass as `relatedPortfolioProjectIds` when calling `apply_to_job_prepare`, `create_productized_service_prepare`, or `update_productized_service_prepare`. To publish a draft project discovered here, call `update_portfolio_project_prepare` with the project's `slug` and `draft: false`, then show the preview and wait for explicit approval before confirming. To move a live project off the public profile without deleting it, call `update_portfolio_project_prepare` with `draft: true`.
Lists reviews received by a user profile, including rating, review text, relationship type, and reviewer details. Returns an aggregate review summary (average score and total count) alongside individual reviews. Use this to evaluate a freelancer's reputation and past client satisfaction. This tool is part of the Talent Discovery Workflow described in search_freelancers — use it during the deep-dive phase to assess review sentiment, client satisfaction patterns, and overall reputation for shortlisted candidates.
Lists all workspaces available to the authenticated user, including their IDs, names, workspace types, studio status, and the active workspace. Use an ID from availableWorkspaceOptions as workspaceId in other tools or in switch_workspace.
Executes a prepared job posting draft by ID and makes the target job public. Only call this after the user has explicitly approved the preview from post_job_prepare.
Prepares posting an existing private job by jobId. Use list_jobs first if the user does not already know the jobId. This tool only changes visibility from private to public. Do not use it to edit job details; use update_job_prepare for that. If the user wants a public community job instead of a Contra-exclusive job, include externalUrl. Show the returned preview to the user and wait for explicit approval before calling post_job_confirm.
Unbookmark a previously saved job on the Contra job board. Use when the user says 'unsave this job', 'remove from bookmarks', or 'I no longer want to follow this one'. The job is removed from the BOOKMARKED preset of list_job_feed.
**MANDATORY FIRST STEP whenever the user provides a URL on `on.contra.com`** (with or without protocol — e.g. `https://on.contra.com/GtRQ8W`, `on.contra.com/GtRQ8W`). Resolves the short URL to its canonical `contra.com` destination URL. The short URL pathname (e.g. `GtRQ8W`) is NOT a slug — do NOT pass it to `get_portfolio_project`, `get_service_by_slug`, `get_product_by_slug`, `get_payment_link_by_slug`, `get_job_by_slug`, or `get_user_profile_by_username`. Always call this tool first to get the real `contra.com` URL, then extract the slug or username from that URL. For URLs that are already on `contra.com`, do NOT call this tool — extract the slug or username directly from the URL and call the appropriate existing tool. After this tool returns, examine the returned `destinationUrl` and call the matching tool: e.g. `contra.com/p/<slug>` → `get_portfolio_project`, `contra.com/<username>` → `get_user_profile_by_username`, `contra.com/s/<slug>` → `get_service_by_slug`, `contra.com/products/<slug>` → `get_product_by_slug`, `contra.com/payment-link/<slug>` → `get_payment_link_by_slug`, `contra.com/opportunity/<slug>` → `get_job_by_slug`. If the destination URL pattern is unfamiliar, fall back to telling the user the canonical link and asking how they want to proceed.
Send the prepared initial message to a job candidate. Only call this after the user has explicitly approved the preview from respond_to_candidate_prepare. This creates a new chat conversation with the candidate and sends the message.
Prepare an initial message to send to a job candidate, starting a conversation with them. Use when the user says 'message them', 'reach out', 'contact this candidate', 'get in touch', or 'send them a message'. This sends the first message only — for follow-up messages after the initial contact, use send_chat_message_prepare instead. **Respond to Candidate Workflow — guide the user naturally through these steps:** **Step 1 · Identify the candidate.** Determine which candidate the user wants to message. If a candidate is not already identified, use `list_job_candidates` to find them. Confirm the correct candidate with the user before proceeding. **Step 2 · Compose the message.** Ask the user what message they want to send to the candidate. The message should be a thoughtful, personalized outreach. **Step 3 · Prepare and preview.** Once the candidate and message are gathered, call this tool to prepare the draft. Show the returned preview to the user and wait for explicit approval before calling `respond_to_candidate_confirm`.
Searches freelancers via discoverSearch (INDEPENDENTS view). Supports roles, skills/tools, expert, location, and language filters. Authenticated searches record inferred role, tool, and industry interests for Contra feed personalization. **Talent Discovery Workflow — optimize for value before intake.** **Exact person lookup:** If the user asks for a specific person by name, username, or @handle (for example "find Jason Obeid" or "@jason"), pass that literal name or handle in `query` and avoid adding role, tool, location, industry, or language filters unless the user also explicitly asks for them. **Phase 1 · Search first:** For requests to find freelancers on Contra, search with the filters available from the user's words, thread context, and profile context. Do not ask for budget, timeline, tools, or industry before the first search. If details are missing, search broadly and state the assumption after results. **Phase 2 · Teaser results:** Present 3-5 usable results with profile links, rate/price data when available, and one-line evidence. Do not show inaccessible counts or a long internal pre-filter list. After the teaser, ask at most two refining questions and include an escape hatch such as "or I can go deeper on these now." If the user gave a full brief, skip questions. **Phase 3 · Pre-filter:** Using the search results' surface-level signals — review averages, relevant tags, title, expert badge, project previews, rate/price fit, and budget fit when supplied — select the top 8-10 candidates most likely to match. Filter hard on a stated budget; if supply does not exist at that budget, say so and offer the job-post path instead of mismatched picks. **Phase 4 · Deep-dive (mandatory before presenting finalists):** For EACH pre-filtered candidate, you MUST call `list_portfolio_projects` (with their `displayUsername`) AND `list_user_reviews` (with their `displayUsername`). Do NOT skip this step. Evaluate each candidate against the user's requirements using these signals, weighted by what matters most to the user: relevance of past projects to the user's domain or industry, match between the candidate's tools/tech and the project's needs, quality and recency of outcomes in portfolio projects, review sentiment and client satisfaction patterns, whether portfolio projects are verified, and recency of work. Discard candidates whose portfolio and reviews do not demonstrate a strong match. **Phase 5 · Present finalists:** Present ~3-5 finalists with a short rationale for each. Every rationale MUST reference specific portfolio projects and specific reviews — not just surface-level profile data. Include rate/price data where available. End with one concrete proposed default action, usually drafting inquiries to the top 3 or the candidates the user named. **Viewing images**: This tool returns `previewUrl` links for avatar and project cover images. **CRITICAL REMINDER: Do NOT present any finalist candidate without first having called `list_portfolio_projects` and `list_user_reviews` for that candidate. Skipping the deep-dive phase produces shallow, unreliable recommendations.**
Searches Contra Studios — the vetted directory of studios at https://contra.com/studios. Studios are hand-vetted creative teams and agencies on Contra, suited for projects that merit more than a single freelancer. **When to use this instead of search_freelancers:** the project spans multiple disciplines (e.g. brand + website + motion), needs parallel workstreams or more capacity than one person can deliver, calls for an end-to-end engagement with one accountable partner, or the user explicitly asks for a studio, agency, or team. For solo-scoped, single-discipline work, use search_freelancers instead. When scope is ambiguous, you may search both and present the trade-off. **Filtering by discipline:** every response includes `availableCategories` — the studio directory categories with their slugs. Pass a slug as `categorySlug` to narrow results to one discipline. Free-text `query`, `locations`, and `languages` filters are also supported. **Evaluating studios:** studios are Contra profiles like freelancers. Follow the same Talent Discovery Workflow described in search_freelancers: search first, show teaser results, pre-filter on surface signals, deep-dive each shortlisted studio with `list_portfolio_projects` and `list_user_reviews` (using its `displayUsername`) before presenting finalists, then propose one default next action. Clients reach out through `send_inquiry_prepare` using the studio's `userProfileId`. A studio's public profile is https://contra.com/{displayUsername}.
Executes a prepared chat message draft by ID via sendChatConversationMessage. Only call this after the user has explicitly approved the preview returned by send_chat_message_prepare. After success, always tell the user the message was sent and include the returned result.chatUrl as the place to view the conversation.
Prepares a chat message for an existing conversation or a new DM. Show the returned preview to the user and wait for explicit approval before calling send_chat_message_confirm. **Step 1:** For existing conversations, identify the conversation (use `list_chat_conversations`). For new DMs, identify the recipient's userProfileId (use `get_user_profile_by_username` or `search_freelancers`). **Step 2:** Ask the user for the message content. **Step 3:** Call this tool with the message, conversation ID (if existing), and/or recipient profile IDs (if new DM).
Executes a prepared inquiry draft by ID via sendPaidProjectInquiry. Only call this after the user has explicitly approved the preview returned by send_inquiry_prepare. After success, always tell the user the inquiry was sent and include the returned result.chatUrl as the place to view the conversation.
**Client Inquiry Workflow — prepare a draft before sending.** **Step 1 · Identify the recipient.** Use the freelancer or studio's `userProfileId` from search results or profile lookup. Do not guess ids. **Step 2 · Pick the inquiry path.** Use an existing `jobId` when the user references one, `productizedServiceId` for a service inquiry, or `jobInput` for a new scoped outreach draft. For new scoped outreach, include `jobInput` only when budget and duration are known or can be safely assumed and stated in the preview. **Step 3 · Draft from context.** When the user explicitly says to send, contact, or apply outreach, draft immediately from thread context and stated assumptions instead of asking another form. Keep the message within Contra's 1,500 character inquiry limit. Once the draft is ready, call this tool. Show the returned preview to the user and wait for one explicit approval before calling `send_inquiry_confirm`.
Mark a job candidate as a good fit by adding them to the shortlist. Use when the user says things like 'this one looks good', 'add to shortlist', 'mark as a fit', 'I like this candidate', or 'thumbs up'. Shortlisting a previously dismissed candidate automatically removes the dismissal. This action is reversible — use unshortlist_candidate to undo it.
Switches the active Contra workspace by workspaceId. Call list_workspaces to discover available workspace IDs. Unified workspaces support both hiring and freelancing without switching roles. The workspace=client|independent aliases are supported only when the current workspace is legacy; Unified users must use workspaceId to select a different workspace.
Restore a previously dismissed candidate back to active consideration. Use when the user says 'undo not a fit', 'give them another look', 'reconsider', 'bring back', or 'un-reject'. This reverses a previous dismiss_candidate action.
Executes a prepared job unposting draft by ID and makes the target job private again. Only call this after the user has explicitly approved the preview from unpost_job_prepare.
Prepares unposting an existing public job by jobId. Use list_jobs first if the user does not already know the jobId. This tool only changes visibility from public to private. Do not use it to edit job details; use update_job_prepare for that. Show the returned preview to the user and wait for explicit approval before calling unpost_job_confirm.
Remove a candidate from the shortlist, returning them to active review. Use when the user says 'remove from shortlist', 'undo fit', 'I changed my mind about this candidate', or 'un-mark as fit'. This reverses a previous shortlist_candidate action.
Executes a prepared job update draft by ID. This only applies detail changes prepared by update_job_prepare. Only call this after the user has explicitly approved the preview.
Prepares a draft to update the details of an existing job by jobId. Use list_jobs first if the user does not already know the jobId. This tool is only for editable job details such as title, description, budget, roles, tools, duration, eligibility, and other job content. Do not use this tool to change visibility. Use post_job_prepare to make a private job public and unpost_job_prepare to make a public job private. Show the returned preview to the user and wait for explicit approval before calling update_job_confirm.
Confirms and applies a portfolio project update from a draft prepared by update_portfolio_project_prepare. Overwrites supplied fields and can publish or unpublish the project. Adding collaborators sends collaboration invitation emails, and existing Contra users also receive notifications. These invitations cannot be recalled. Requires a draftId, confirm: true, and explicit user approval of the preview and any collaborator invitations. The response includes the current slug and projectUrl after the update; use those returned values for any later portfolio project calls because title changes can change the slug.
Prepares an update to an existing portfolio project by slug and returns a draft preview. Only provided fields are changed — omitted fields remain unchanged. If content or coverImageUrl are provided, images are uploaded during prepare. Standalone Vimeo and YouTube URLs placed on their own line are embedded inline in the project body. Inline media.contra.com image URLs can be reused directly; other image URLs must be publicly accessible. 📢 **Publish/draft state is controlled by the `draft` field ONLY.** The project's publish state (visible on the public portfolio vs. hidden as a draft) is stored internally as a `publishedAt` timestamp, but the user-facing control is the `draft` boolean. Set `draft: true` to move a live project back to draft, set `draft: false` to publish a draft project, or OMIT the field to leave the current publish state exactly as it is. Updating any other field (title, content, roles, etc.) without setting `draft` will NOT change the publish state — existing drafts stay drafts, existing live projects stay live. ⚠️ **FULL-REPLACEMENT FIELDS — BE CAREFUL.** The following fields behave as **full replacements** when provided: `roles`, `tools`, `collaborators`, `organizations`, `industries`, and `content`. Passing a list for any list field replaces the entire existing list on the project, **silently removing anything not included**. Passing `content` replaces the entire project body. To add a single list item, you MUST include every existing item plus the new one. To add an inline image or supported video embed to existing content, you MUST fetch the current project first and pass the complete final content body, preserving the saved text and inserting the markdown image block or standalone video URL in the requested section. To preserve a field, OMIT it entirely from the update. All other fields (`title`, `description`, `coverImageUrl`, `externalLinkUrl`, `startedAt`, `endedAt`, `draft`) use partial-update semantics — omitting means "don't change this". **Portfolio Project Update Workflow — guide the user naturally through these steps:** **Step 1 · Identify the project.** Identify the portfolio project to update. Call `get_portfolio_project` with the slug to load the current state — you will need the existing values for the preview diff, to construct full-replacement lists, and to preserve existing body text when updating `content`. **Step 2 · Gather changes.** Ask which fields the user wants to change and collect the new values. **Step 3 · Assemble full-replacement values carefully.** If the user wants to change `roles`, `tools`, `collaborators`, `organizations`, or `industries`, combine their requested changes with the existing values from step 1 to form the complete final list. Never pass a partial list — the API treats any list you send as the full desired state. If the user wants to add or move an inline image or supported video embed in the project body, build the complete final `content` value from the current project content plus the markdown image block or standalone video URL; never send only the image markdown or video URL unless the user truly wants to replace the entire body with just that media. Once all information is gathered, call this tool to prepare the draft. **MANDATORY preview display — before calling `update_portfolio_project_confirm`, you MUST show the user every row from the returned `preview.changes` array so they have full understanding of what is changing.** Each row is a `{ label, from, to, note? }` object already formatted for humans in plain language: - `label` — the human-readable field name (use verbatim, do NOT replace with camelCase identifiers). - `from` — the current value on the existing project. - `to` — the new value that will be applied. - `note` — (when present) a warning explaining which items will be REMOVED for full-replacement fields. Always show the note verbatim when present. Present each row as a simple "LABEL: from → to" line, followed by the note on a new line if present. Do NOT invent field names, do NOT use camelCase, do NOT skip any row. If `preview.changes` is empty, there is nothing to apply — tell the user and do not call confirm. If `preview.warning` is a string, surface it prominently above the change list so the user sees it before the diff. Only call `update_portfolio_project_confirm` after the user has explicitly approved the full change list.
Returns the current authenticated visitor/userAccount, if any.
Contra ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve Contra's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Contra alternatives on ChatGPT?
As of 2026-11-12, Contra competes with American Traveler Jobs, Fiverr, Folkso, Fonzi Talent, GetMeDesign, Hacesfalta, HireTalent.lat, Lawtrades and 9 more in ChatGPT Talent Marketplaces & Freelance Hiring, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.


