AI Providers and Endpoints
Use this page to call the AI routes, tune background scoring, or add your own AI provider.
The AI hiring tools (applicant ranking, fit scores, applicant TL;DR
summaries, candidate-to-job matching, AI job-description and
cover-letter writing) live in modules/ai/. They are driver-based:
one driver per provider, all behind a common interface, with a
filter to register a fourth provider from an addon.
Built-in providers: Anthropic Claude, OpenAI, and self-hosted Ollama. Providers are chosen per task - an analysis and ranking provider (Claude, OpenAI, or Ollama) and an embedding/matching provider (OpenAI or Ollama) - each with its own key, under Settings > AI Settings.
REST endpoints
Section titled “REST endpoints”All AI routes live under the shared wcb/v1 namespace and are
registered by api/endpoints/class-ai-endpoint.php. Every route checks
who may call it (the license never gates them - see the licensing note below)
and counts against a per-user rate limit of 30 AI requests per hour (counted only after the permission check passes); the
31st returns wcb_rate_limited with HTTP 429.
| Method | Route | Permission | Purpose |
|---|---|---|---|
| POST | /wcb/v1/ai/match |
logged in | Jobs that match a natural-language query (AI Chat Search) or the current user’s resume. Needs an embedding provider. |
| GET | /wcb/v1/candidates/{id}/matches |
that user, or wcb/manage-ai |
“Recommended for you” jobs for a candidate. Needs an embedding provider. |
| GET | /wcb/v1/ai/ranked-applications/{job_id} |
wcb/view-applications, and the job’s author (or wcb/manage-settings / wcb/moderate-jobs) |
Applicants for a job, best fit first. Unscored applicants have score: null and are queued for background scoring. |
| POST | /wcb/v1/jobs/ai-description |
wcb/post-jobs |
Generate a job description. |
| POST | /wcb/v1/jobs/{job_id}/ai-cover-letter |
wcb/apply-jobs |
Generate a cover letter from the candidate’s resume and a published job. 404 for any other status, 503 when no analysis provider is set. |
Fit scores, reasons, and summaries are cached per application (in
the _wcbp_ai_fit_score, _wcbp_ai_fit_reason, and
_wcbp_ai_summary meta family, plus _wcbp_ai_scored_at), so
re-opening the Employer Dashboard never re-bills the model; ranking
computes only what is missing.
Scoring and “not scored”
Section titled “Scoring and “not scored””AiModule::score_application( $app_id, $force = false ) returns
{ application_id, score, reason, summary }. When the provider errors or
its reply has no numeric score, it returns score: null with
not_scored: true, saves nothing, and schedules another try 5, 10 and 20
minutes later (tracked in _wcbp_ai_score_tries, three tries). A failed
call is never stored as a 0% fit. The dashboard shows “Not scored”.
The model reads the job title and description (4,000 characters) and the application: cover letter, answers to the application form fields, and the chosen resume, else the profile resume (6,000 characters together).
| Filter | Default | Use to |
|---|---|---|
wcbp_ai_score_batch_size |
25 (1-100) | Applications scored per background pass |
wcbp_ai_rank_max_applications |
500 | Applications one ranking pass considers per job |
wcbp_ai_match_scan_cap |
2000 | Job vectors scanned per matching search |
Auto-scoring on submit
Section titled “Auto-scoring on submit”When “Auto-score applicants on submit” is enabled (Settings > AI
Settings, option wcbp_ai_auto_rank), Pro schedules a single cron
event to score each new application in the background, unless one is
already queued for it:
wp_schedule_single_event( time() + 30, 'wcbp_ai_score_application', array( $app_id ) );The handler AiModule::run_scheduled_scoring() listens on the
wcbp_ai_score_application action. To trigger scoring yourself,
fire that action with an application id. An explicit rank request queues
one wcbp_ai_score_job_batch event per job instead, which scores a batch
of unscored applications and re-arms itself until the job is drained.
The driver interface
Section titled “The driver interface”Every provider implements AiDriverInterface
(modules/ai/class-ai-driver-interface.php):
interface AiDriverInterface { public function embed( string $text ): array|\WP_Error; // vector for matching public function complete( string $prompt ): string|\WP_Error; // text generation public function provider_name(): string;}The built-in drivers are ClaudeDriver, OpenAiDriver, and
OllamaDriver, all in modules/ai/.
Adding another provider
Section titled “Adding another provider”The driver registry is a provider_slug => factory_callable map
run through the wcbp_ai_provider_drivers filter. Add a slug to
ship your own provider:
add_filter( 'wcbp_ai_provider_drivers', function ( array $drivers, string $credential, string $base_url ) { $drivers['my_llm'] = static function () use ( $credential ): \WCB\Pro\Modules\Ai\AiDriverInterface { return new \MyAddon\Ai\MyLlmDriver( $credential ); }; return $drivers;}, 10, 3 );Then make your provider selectable by registering it in the AI
settings UI, or set the relevant option
(wcbp_ai_completion_provider / wcbp_ai_embedding_provider)
to your slug.
If your provider does not need an API key (for example a
self-hosted endpoint), tell Pro via the
wcbp_ai_provider_requires_api_key filter:
add_filter( 'wcbp_ai_provider_requires_api_key', function ( bool $requires, string $provider ) { return 'my_llm' === $provider ? false : $requires;}, 10, 2 );Model selection
Section titled “Model selection”Each provider’s model is configurable so you can trade quality for
cost. For Claude, the model is resolved through the
wcbp_ai_claude_model filter (default reads the
wcbp_ai_anthropic_model option, or the driver’s built-in default when unset). To force a model:
add_filter( 'wcbp_ai_claude_model', fn() => 'your-claude-model-id' );Output and input filters
Section titled “Output and input filters”| Filter | Args | Use to |
|---|---|---|
wcbp_candidate_resume_data |
$user_id |
Override the grouped resume data Pro feeds the model when scoring or matching a candidate. |
wcbp_ai_candidate_matches |
$matches, $user_id |
Post-process the candidate match results before they are returned. |
wcbp_ai_ranked_applications |
$ranked, $job_id |
Post-process the applicant ranking before it is returned. |
Licensing
Section titled “Licensing”Like every Pro feature, the AI tools are not gated on the license. The license drives automatic updates only; once Pro is installed and a provider key is set, the AI endpoints work regardless of license status. See 02-extending-free.md for the contract.
Related
Section titled “Related”- AI feature walkthrough (admin/end-user): ../ai-features/01-overview.md
- Pro hooks reference (the AI hooks in context): 03-hooks-reference.md

