Overview
EnskAI is the platform football agencies run their business on. This app lets an agency's staff work their book from ChatGPT: search the shared player and club catalogue as well as their own roster, read the briefs clubs have sent and rank their players against them, review scouting reports and injury and career history, see which deals have gone quiet, and check contract expiries and agency finances. It also writes back — onboarding a player, filing a scouting report, moving a deal along, logging a club note or proposing a player to a club. Every call is scoped by the EnskAI backend to the signed-in user's organization and role.
Tools
enskai_book_summary
ChatGPTkey is reusable as a filter on search_players, so "the 14 expiring in 2027" can be listed by passing that year's window straight through. A null key is the "not set" bucket. group_by="transfer_windows" instead returns when windows open and close by country (season start/end and both registration periods, men's professional). Use it whenever a deadline matters — "how long have we got in Poland?" — rather than answering from general knowledge, which goes stale every season.enskai_check_player_onboarded
ChatGPT{onboarded, player}. When onboarded is true, player is the existing record (its id UUID, name, …) — tell the user they're already in the org and offer to open or update that record instead of creating a duplicate. When false, it's safe to onboard. onboarded is true with visible_to_you: false and no player when the organization holds the record but this caller's role or its visibility settings hide it. Do NOT onboard in that case — it would create a second record for the same player. Say the player is already in the organization on a record they cannot open.enskai_contract_dashboard
ChatGPTexpiring: split into the next 30 days, the next 12 months by month, and recently expired. Offer to create a renewal task for any of them. - payments_due: instalments and invoices owed, with overdue_count and total_outstanding. Each item carries its own currency — money is held in the currency it was agreed in. Quote total_outstanding only when outstanding_by_currency has a single entry; with more than one, give those figures instead and say they are separate currencies, never a single total. - missing_contracts: players on the book with no contract recorded — a data-quality list worth raising proactively. Needs the legal module; a 403 means the organization doesn't have it.enskai_financial_forecast
ChatGPTpaid (already received), overdue (due date passed, unpaid), guaranteed (due in future, unpaid), expenses, and profit. Months with no money are omitted. unscheduled_revenue_amount is money with no due date, so it sits in no month. performance_included is false: income from contract performance clauses is not yet computed, so say the figure excludes clause income rather than presenting it as the complete picture.enskai_financial_summary
ChatGPTtotals (revenue, received, expenses, outstanding, net result, currency) plus revenue and expenses grouped by year, with a count per year rather than the individual rows. A year of null means those items have no due date set. To read one underlying item use search_finances, then get_record.enskai_find_opportunities
ChatGPTlimit of a ranked list, each with the routes in named — the decision-makers who worked with the player, the ex-teammates now on a club's staff, the club's open briefs. total says how many there were; offer to go wider rather than implying the list is all of them. Needs the opportunity_finder module; a 403 means the organization doesn't have it — say so rather than falling back to guesswork.enskai_get_club
ChatGPTenskai_get_club_fixtures
ChatGPTenskai_get_club_knockout
ChatGPThas_knockouts from get_club_standings first — many leagues have none, and this returns an empty list for those.enskai_get_club_squad
ChatGPTin_my_organization, so you can tell at a glance who is already on the books. player_id is the numeric Wyscout id: pass it to player_statistics or lookup_wyscout, NOT to tools that expect the org record UUID.enskai_get_club_standings
ChatGPThas_knockouts — when true, the competition also has a playoff/knockout phase you can read with get_club_knockout.enskai_get_filter_options
ChatGPTcontrol_stages, quality_grades and potential_grades, and for "scouting_reports" the grades: the names a record can be set to, in list order. Each organization configures these lists, so read them here rather than assuming a stage or grade exists.enskai_get_record
ChatGPTenskai_list_activity_stages
ChatGPTname (what to pass as stage), id (pass as stage_id when names are ambiguous), pipeline, board position, and is_default — the stage a new activity lands in when none is given. Retired stages are excluded: they remain on old activities as history but are not valid destinations.enskai_lookup_matches
ChatGPTplayer_id to list that player's matches, or query to search by a match label. Returns the raw candidate list — use the right entry's matchId on manage_scouting_report.enskai_lookup_org_members
ChatGPTid for assigned_to_record (assignment), staff_id (contract parties), or sharing. A staff member also carries transfermarkt_staff_id — the external catalogue's id, which is what market tools such as find_opportunities search on. They are different ids for the same person; don't substitute one for the other. Returns {items, total}. The lists are small, so this filters client-side by search rather than paging.enskai_lookup_staff_by_team
ChatGPTteam_id to its current staff in the Transfermarkt catalogue — head_coach, assistant_coach, sporting_director, coaching_staff, club_executives, scouting — each with their role, tenure (appointed / in_charge_until) and league/country. This is the ONLY tool that answers "who is the coach/SD at club X"; do not infer or state a person's club or role from anything else. Returns {team_id, staff: [...]}. An empty staff list means the catalogue has no current staff on record for that club — say so plainly rather than guessing a name. Resolve the club first with lookup_wyscout(kind="team").enskai_lookup_wyscout
ChatGPTenskai_mailing_lists
ChatGPTis_default. Members with no email address are returned but cannot be notified — say so rather than dropping them silently. Reading and composing only: sending a campaign is done in the platform.enskai_manage_activities_bulk
ChatGPTstage accepts the org's own configured stage names (see list_activity_stages); resolve the name once before the call rather than per record. Each record is applied independently, so one failure never blocks the rest. Returns succeeded/failed counts and a results array with, per record, ok=true and the saved record or ok=false and an actionable error. Only updates are supported; create with manage_activity.enskai_manage_activity
ChatGPTtype (deal|task) and title. Set player_id and/or team_id to tie it to a player/team. Use due_date for tasks and next_action for deals — a date with no time falls due at 09:00 in the user's timezone, so pass a time only when they named one. player_id can only be set at create time. Set parent_activity_id to make a task a subtask of another task, and priority (low|medium|high) on either. UPDATE needs activity_id; pass only the fields you want to change (type cannot change). Omitted fields are left untouched. stage is a free-text name resolved against this organization's own stages, which it can rename and add to — use list_activity_stages rather than assuming which stages exist. On create, omitting it lands the activity in the org's default stage. Returns the saved activity. A 403 means the caller's role can't write it; a 422 means a value was rejected — fix it and retry. A 400 naming a stage means that stage isn't in the org's pipeline (or is retired) — read the live list and pick one that is.enskai_manage_contact
ChatGPTfirst_name/last_name. For a STAFF contact, link the club with team_id (Wyscout) and/or staff_id (Transfermarkt) rather than a free-text organization: the backend derives the club name from the link and blanks the free-text field for staff. Resolve both ids with lookup_wyscout (for a coach, its staff_id equals the Transfermarkt trainer id). UPDATE needs contact_id; pass only the fields you want to change. Omitted fields are left untouched. Note: changing category makes the backend clear the now-irrelevant club/agency link. Returns the saved contact. A 403 means the caller's role can't write it; a 422 means a value was rejected — fix it and retry.enskai_manage_contract
ChatGPTextra dict for anything else — use the backend's exact field names there. CREATE needs contract_type and active_status. UPDATE needs contract_id and replaces the contract with the fields you send, so fetch it first with get_contract, then resend the full set you want kept plus your changes. Returns the saved contract. A 403 means the legal module is disabled or the role can't write it; a 422 means a value was rejected — fix it and retry.enskai_manage_finance
ChatGPTkind and amount. UPDATE needs kind and finance_id; pass only the fields you want to change. The invoiced lifecycle (invoiced, invoiced_at) and player_clause_id apply to revenue only and are dropped for expenses. Returns the saved item. A 403 means the legal module is disabled or the role can't write it; a 422 means a value was rejected — fix it and retry.enskai_manage_player
ChatGPTwyscout_player_id (resolve a name with lookup_wyscout) and/or tm_player_id (the number in a Transfermarkt link); both go to the SAME endpoint and the backend builds the full record from it. Any enrichment fields you also pass (control_stage, transfer_strategy, quality, potential, prices, salaries, description, video_link, tags, assignments, associations) are applied automatically right after, so a scouted player is onboarded complete in ONE call. (If the created record can't be resolved to apply them, the result carries pending_enrichment=true so you follow up with op="update".) If a Transfermarkt id can't be resolved (its data isn't in the catalogue yet), resolve the player's NAME with lookup_wyscout and onboard with that wyscout_player_id instead. UPDATE needs BOTH player_record_id (the UUID, picks the record) AND wyscout_player_id (the numeric id, required in the body). Pass only the fields you want to change; omitted fields are left untouched. Quality and potential use a -1..13 scale: -1 means not yet rated (shown as "Pending review" — NOT a low score, and distinct from 1), 1-12 are the letter grades D- through A+, and 13 marks a youth player too young for the senior scale. Send the number; responses render the label. Returns the saved player record. A 403 means the caller's role can't write this record; a 422 means a value was rejected — fix it and retry.enskai_manage_players_bulk
ChatGPTplayer_record_id and wyscout_player_id; include only the fields you want to change. Returns succeeded/failed counts and a results array carrying, per record, ok=true with the saved record or ok=false with an actionable error — retry just the failed ones. Only updates are supported here. Create players with manage_player (a Wyscout create can enrich in the same call).enskai_manage_proposal_or_nudge
ChatGPTpropose_player is the proper way to put a player forward: it records the proposal, opens the deal in the org's default stage and notifies — all of which a hand-made manage_activity call would miss. Both records must belong to the caller's organization. Resolve the player with search_players and the request with search_team_requests first, and name both in the confirmation so the user can catch a wrong match. nudge sends a push to the named people about the named deals — one per (deal, recipient). Use it when the user asks to chase someone, typically straight after work_queue surfaces a stale deal.enskai_manage_scouting_report
ChatGPTplayer_id (the record UUID from search_players). Tie it to a match with match_id (from lookup_matches) OR the manual_* fields when the match isn't in the system. Quality and potential use a -1..13 scale: -1 means not yet rated (shown as "Pending review" — NOT a low score, and distinct from 1), 1-12 are the letter grades D- through A+, and 13 marks a youth player too young for the senior scale. Send the number; responses render the label. If you leave them unrated, don't imply you scored the player. UPDATE needs report_id; pass only the fields you want to change. Omitted fields are left untouched. Returns the saved report. A 403 means the module is disabled or the role can't write it; a 422 means a value was rejected — fix it and retry.enskai_manage_scouting_reports_bulk
ChatGPTsucceeded/failed counts and a results array with, per record, ok=true and the saved record or ok=false and an actionable error. Only updates are supported; create with manage_scouting_report.enskai_manage_team_note
ChatGPTenskai_manage_team_request
ChatGPTteam_id, position and type. One position per request: if a club wants multiple positions, call this once per position (copy the club-level budget/window/contact to each). UPDATE needs team_request_id; pass only the fields you want to change. Omitted fields are left untouched. The request is saved SILENTLY unless you pass notify_emails. The website offers a "notify" tick that emails the brief to chosen people plus everyone assigned to that club; this is the same thing. Don't send unprompted — but when a club has colleagues covering it, it is worth asking whether to tell them, since they would have been emailed had the request been logged on the website. search_clubs(team_id) shows who covers a club. Returns the saved team request. A 403 means the caller's role can't write it; a 422 means a value was rejected — fix it and retry.enskai_match_players_for_request
ChatGPTlimit players ranked by suitability for this brief, each with a 0–5 suitability_rating, price/salary, age, contract runway and pipeline stage — plus total, the full count of suitable players, so you can report "showing N of total". Pass a player's id to get_record(resource="players") for full detail. The brief's hard constraints are applied automatically: this tool reads the request's own max_age, max_value, max_net_salary and eu_passport and filters by them (age is a hard cap; the money caps get the platform's 20% negotiation tolerance), so the result matches the web view instead of an unfiltered, wrongly-ranked pool. The constraints actually applied are echoed back in applied_constraints. To override, pass any of age_max, club_asking_price_max, max_net_salary, eu_passport explicitly — an explicit value (including a deliberately loose one) wins over the auto-filled one. Every filter is null-safe — a player missing that datum is kept, not hidden. Scores are computed live from current ratings, so a request matches as soon as it exists — no evaluation step. A 404 means the request id is wrong or not visible to you — resolve it with search_team_requests first. Empty results are normal when no player in your organization plays the requested position for that window (or the clubs involved sit in a competition without rating coverage).enskai_match_requests_for_player
ChatGPTprivate (your own organization's requests) and community (shared requests from other agencies). Each bucket has the top limit requests ranked by suitability — club, position, window, deal type, budget and a 0–5 suitability_rating — plus its total. Pass a request's id to get_record(resource="team_requests") for full detail. The suitability score ranks on playing-level fit; it does NOT by itself enforce a brief's hard requirements, so pass respect_constraints=true to drop briefs this player is ineligible for (too old, non-EU when required, over the brief's budget or wage ceiling). A 404 means the player-record id is wrong or not visible — resolve it with search_players first. Empty results are normal when there are no open briefs for the player's position in the current window (or the player's club sits in a competition without rating coverage).enskai_player_career
ChatGPTtransfers (each with from/to club, date, type and fee), club_totals (appearances, starts, goals, cards across his career) and international (national team, caps, goals, minutes) — fetched together because these are almost always wanted together. For form over a recent period use player_statistics instead; this is the whole career. A transfer with an implausible date or a missing fee is a gap in the source data — report it as unknown rather than inferring one.enskai_player_form
ChatGPTstate says why a row has no rating: did_not_play (club played without him), not_covered (competition has no Sportmonks ratings), unrated (he played, no rating collected). Only rated rows count toward average. Never call a missing rating a bad game, and don't read did_not_play as an injury — use player_injuries. rated_count: 0 means no rated form: say so, don't guess.enskai_player_injuries
ChatGPTgames_missed and active_injury (true = still out). Set current_only for just the live ones. An empty list means no recorded injuries — say that, rather than that he is fit.enskai_player_statistics
ChatGPTtotals plus a by_competition breakdown (matches, starts, sub_appearances, minutes, goals, assists, goal_contributions, yellow/red cards). Friendlies are excluded; continental cups (Champions League, Libertadores, …) are included. Resolve the player's numeric player_id with lookup_wyscout(kind= "player") FIRST — not search_players, which only covers players onboarded in your org. Because this reads the global Wyscout data it works for any player regardless of org, so prefer it over general knowledge for real match numbers. For all-time totals use period="career" (or career_summary); for individual games use lookup_matches. The response echoes the resolved window in period; check period.resolved_from to see how a fuzzy season was pinned (e.g. "Serie A 2024/2025").enskai_read_comments
ChatGPTenskai_read_team_notes
ChatGPTenskai_reports_for_player
ChatGPTenskai_search_activities
ChatGPTtotal field (the full match count) — never count items, which is only the current page.enskai_search_clubs
ChatGPTassigned_to to answer "which clubs does <person> cover?" — pass their platform user id (from lookup_org_members), not their name. Returns {items, total, offset, limit, has_more, next_offset}. Use total when asked how many, never the number of rows shown.enskai_search_contacts
ChatGPTtotal field (the full match count) — never count items, which is only the current page.enskai_search_contracts
ChatGPTlegal module; scoped to the caller's organization, role and visibility. When has_more is true, call again with offset set to next_offset. contract_type is a constrained enum (valid values are in the schema — no pre-flight needed). Note: agent / agent_id is the contract's agent; notify is a separate list of people cc'd on reminders. Being in notify does NOT make someone the agent or the owner — don't infer ownership from it. Many contracts have no agent set at all (agent/agent_id null), and the backend has no "belongs to me" concept; visibility is org-scoped.enskai_search_finances
ChatGPTtotal field (the full match count) — never count items, which is only the current page.enskai_search_market_players
ChatGPTtotal says how many players match, shown how many are returned, and capped whether there are more. Always tell the user what they're looking at — "the 50 best matches out of 4,127" — rather than implying the list is everything. There is no next page, by design: this is the catalogue, and the useful next step is a sharper question, not more rows. When capped is true, say so plainly and offer to narrow — by age, division, contract window, minutes played — rather than apologising for a limit or implying the data is withheld. narrowing_hint in the response suggests which filter would help most. The shortlist can be widened to max_shortlist at a push, but a 4,000-match query wants a better filter, not a longer list. Ranking defaults to market value, descending. Set sort_by when the question implies another order (contract expiry for expiring deals, age for youth) — with a cap in play, the ranking decides who makes the cut, so it matters more here than on your own book.enskai_search_players
ChatGPTtags is org-defined, so call get_filter_options(resource="players") when you need the exact tag set. Filter by current club (team_id), team_country, passport_country (nationality) or area_league ("League|Area", e.g. "Premier League|England"). For a "how many" question read the total field (the full match count) — never count items, which is only the current page.enskai_search_scouting_reports
ChatGPTenskai_search_team_requests
ChatGPTtotal field (the full match count) — never count items, which is only the current page.enskai_triggers_for_player
ChatGPTenskai_work_queue
ChatGPTtriggers: things the platform spotted (a player left a club you follow, a staff move, an opportunity). importance ranks them. - stale_deals: open deals with no update inside the org's threshold, or whose next action is already past — oldest first. This is a maintenance queue, not a report; each row is a deal to chase, snooze or close. - newsfeed: what colleagues changed recently. Each queue reports its own total, which may exceed the rows shown — quote the total when asked how many.fetch
ChatGPTsearch. Returns the complete record as readable text for analysis and citation.search
ChatGPTid to fetch to read the full record. Scoped to the authenticated user.Capabilities
Example Prompts
Click any prompt to copy it.
Links
App Stats
54
Tools
3
Prompts
ChatGPT
Platforms
Category
Company ResearchWorks with
Similar Apps
Data refreshed daily





