- Brand
- EULER
- Category
- Sales & CRM
- Primary Subcategory
- Partner & Ecosystem Revenue
Integration details
Description
Manage your partner program and access your Partner Data Lake with ChatGPT. Instant actions and answers on deals, commissions, onboarding, and partner performance, no dashboard required. Partners can register deals and access live data across their pipeline, enablement, certifications, payouts and more.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Partner & Ecosystem Revenue
- Secondary Subcategories
- None listed
- Brand
- EULER
- Access
- Account required
- First tracked
- 2026-09-13
- Tool count
- 60
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for EULER
Get updates when EULER’s Discoverability Score or category rank changes.
Competing in ChatGPT Partner & Ecosystem Revenue
View Category60 tools agents can invoke
[Partners — general management] Approves or rejects a PENDING partner-registration application. Approving runs the company's onboarding: it finds or creates the partner and the partner contact from the answers, stamps the application approved, syncs to the connected CRM, applies tags and mints an affiliate link — except on a Salesforce form that creates partners in the CRM only, where it creates NO partner and no partner contact here, only the CRM record; the partner arrives later via CRM sync, so do not wait for a partner_id or promise one. Rejecting stamps it rejected with reason and decider. Both are ASYNCHRONOUS: the response reports application_status 'approving' or 'rejecting' while the application is still pending, and accept_scheduled means an accept was scheduled, not that a partner exists. The response has no partner_id: otherwise read it a few seconds later from partner_applications(action:'get'); invite_partners_to_portal and flows_manage need it. Only a pending application can be decided, and only once; a referral belongs to resolve_referral.
resolve_partner_application
[Partner Relationships] Approve or reject a PENDING referral. Works in both directions, and who may decide depends on the direction — the tool figures this out from the referral itself, you do not pass a direction. Inbound (a partner submitted it to the company): the CUSTOMER decides; approving creates the referral in the company's CRM. Outbound (the company sent it to a partner): the PARTNER decides; approving accepts the lead, reveals the form answers and opens the deal. You can only resolve a referral addressed to you — resolving someone else's returns an authorization error. Find resolvable referrals with referrals(action:'search') as a customer or referrals(action:'for_partner') as a partner; only status='pending' can be resolved, and only once. Rejecting an INBOUND referral requires a rejection reason when the company has them configured — list them first with referrals(action:'rejection_reasons'). Outbound rejections take a free-text note instead. Optionally email the other side about the decision via notify_partner + notification_details.
resolve_referral
[SI Service Projects — Customer Admin] Customer-admin decisions on SI (System Integrator) service projects — approving or rejecting a partner's project, one at a time or in bulk, which is how a large backlog of junk submissions gets cleared. A batch returns one result per project plus counts, where `processed` is how many were attempted on that page and `not_found` are ids that are not your company's, skipped with nothing changed. The customer company is resolved server-side, so a project outside it is simply not found. Projects and their scope forms are read with si_customer_service_projects, which is also where the project ids come from; this tool only changes approval status.
si_customer_manage_service_project
[Partner Directory] Read and author your Partner Directory: read a profile's editable content, add partners to the directory, rewrite a profile's content, and add or remove a profile resource (Testimonial, Resource, Case Study, Client, Video, Top Service, Certification — those exact seven, matched on the option's display text). Takes `profile_id` values from `partner_directory_search` (NOT partner_ids) - except action='add_partners', which takes partner_ids because the profile does not exist yet. action='read_profile' returns the CURRENT value of every field write_profile can set (name, website, short_description, long_description, accepting_clients, hide_contact_button) - it is the only way to read website and the two flags, which no search mode returns. action='write_profile' overwrites ONLY the fields you send: omit a field and its current value is kept, so you never have to restate what you are not changing, and you must never guess a value to fill a slot. accepting_clients and hide_contact_button are the exception - they are always written, so read them first with read_profile and pass them back. Fields this tool does not expose at all (logo, address, languages, custom filter answers, resources) are carried over untouched. A write by a customer admin publishes immediately (status Active); the review queue is for partner-side edits. The public directory is a cached JSON blob refreshed on a ~10-minute cycle, so a change is not visible on the public page immediately. To EDIT a resource, remove it and add it again - editing in place is not offered because a resource carries no link back to its profile, so it cannot be scoped to your directory.
partner_directory_profiles
[Content Management — Customer Admin] Finds the company's content items, folders and content categories: the read side of the customer-admin content library. It covers ALL of the company's content, not just what one partner sees — that is `content_search`/`content_list` — and returns the content_id, folder_id and category ids the write actions need. Folders are FLAT, with no nesting, and every content item needs at least one category, so list the categories BEFORE content_manage(action:'create'). Filter values must match EXACTLY what this tool returns for that field (case-sensitive); other spellings are rejected. Content and folder rows carry raw `visibility`/`share_with_all` plus a derived `effective_visibility` — trust the derived one and flag `visibility_conflict: true` items to the user instead of guessing from the raw pair — and `shared_partner_ids`/`shared_tag_ids`, which are populated only for 'Selected Partners' and 'Partner Tags' visibility and empty otherwise, as expected rather than in error.
content_admin
[Partner Relationships] Inspects specific charges. action='for_deal' returns every charge linked to a deal_id ('show me what was charged on deal X'); action='by_id' returns one charge in full — amount, commission, partner, date, status ('inspect charge xyz'). Customer-only. Partner-scoped charge lists are `partner_artifacts(action: 'charges')`.
charges_lookup
[Commissions & Payouts] Commission payouts and expense over a date range; start_date and end_date are required, with no defaults. action='company' answers the third-person aggregate ('how much did we pay', 'company-wide payout', 'total spent on partner commissions') and is customer-only. action='partner' answers first-person and single-partner questions ('how much commission did I earn this month', 'minha comissão', 'commission owed to <Partner X>') and needs partner_id. For action='partner': Reading the response: `commission_status` is the payout's own status, matching the Payments tab ('Created by Partner' shows there as Awaiting Confirmation; empty means no payout activity yet), while `customer_payment_status` is the end customer's billing status for the deal and never says whether a commission was paid. `charge_type` gives the direction — 'Outbound' is a deal your company sent the partner, so the commission is owed to you; 'Referral' and 'Reseller' are deals the partner sent you, so you owe them. `commission_Sum` mixes both directions; for what a partner owes you use `commission_sum_outbound` and `commission_sum_awaiting`. The supplied sums and counts (`total_charges`, `count_outbound`, `count_awaiting`) are authoritative — never recompute them from `list_of_charges`, which may hold several charges for one `deal_name` and must not be merged by name; each row is identified by `charge_id`. Per charge, `commission_to_be_paid` is the commission and `amount` the charge it was calculated from. A period with no charges returns 0 and an empty list, which is a valid answer. An {"error":"partner_not_found"} response means the partner_id matched nothing: re-resolve it and retry rather than reporting a zero. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
commissions
[Communications Hub] Read-only view of the Communications Hub, the partner email program. action='list_audiences' lists the company's audiences with their active flag and contact count; action='list_templates' lists email templates; action='list_sent_emails' lists individually-sent emails with status, opens and clicks; action='emails_by_broadcast' lists the emails sent in one broadcast. action='preview_broadcast' returns how many recipients an audience plus template would reach, with a sample of eligible contacts — call it before sending. action='preview_template' renders a template with one contact's data substituted, so the final email can be shown. Everything is scoped to the user's company automatically.
communications
[Communications Hub] Creates and sends within the Communications Hub, the partner email program. action='create_audience' creates an empty partner audience. action='create_template' creates an email template from raw HTML; the only merge tokens it accepts are [Contact First Name], [Contact Last Name], [Contact Email] and [Company Contact], and any other token is rejected before saving. action='add_contacts' adds up to 100 partners to an audience and skips partners already in it. action='send_broadcast' sends a template to every eligible contact of an audience — it emails real partners and cannot be undone, so call communications(action:'preview_broadcast') first and pass confirm=true only after the user explicitly approves. Everything is scoped to the user's company automatically.
communications_manage
[Partner Relationships] Creates or updates deals attributed to your partners. action='create'/'update' handle one deal; action='create_batch'/'update_batch' handle many at once. Batch operations are scheduled and run in the background — the response confirms how many were queued (schedule_amount) and does not return the rows, so confirm the result later with get_search_deals rather than resubmitting. Every deal validates its partner against your company. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
manage_deals
[Partner Contacts & Portal Invites] Creates a partner contact — a person inside a partner organisation — for a given partner. Idempotent: a contact with the same email already on that partner is returned as it stands with `was_created: false`, and no duplicate is made. Use it to add a new person BEFORE granting them portal access with `invite_partners_to_portal`, which takes contact ids rather than emails. Customer-side only. Nothing is created when partner_id does not exist at all (rejected upstream — the usual sign of a typo or a stale id, so ask the user to verify the partner) or when it belongs to a different company than the caller's (an empty response rather than an error). partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
create_partner_contact
[Partner Relationships] Creates an affiliate/tracking link for ONE of your company's partners (customer-admin only — partners read their own links with `partner_artifacts(action: 'tracking_links')` and cannot create them). It wraps a destination URL with an auto-generated 6-char tracking id (`eid`) and any extra query parameters. On a repeat of an existing (partner_id, label) the response carries status='Duplicated' and the existing URL in `AI_instruction` rather than in `link`. The link is created immediately, so confirm the destination URL and the label with the user first. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
create_tracking_link
[Customer — Users & Roles] Reads the internal users and roles of the customer admin's OWN company. ⚠️ The user list is the company's FULL roster, not its active one: DEACTIVATED users are returned alongside active ones on purpose, because `manage_customer_users` action='reactivate_user' has to be able to find them. Read each user's `deactivated` flag before you count a company's active users, describe its team, or act on anyone; if that flag is absent from the user objects entirely, this backend predates it and every user's status is UNKNOWN — say so rather than assuming they are all active. A user has exactly one role at a time, or none, never several, and a role reports how many of the company's users hold it. Neither action takes parameters: the company always comes from the caller's own session, never from an argument.
customer_users
[Performance & Rankings] Aggregates deals server-side and returns plot-ready buckets: one row per group carrying deal_count, total_amount and average_amount, already summed. Use it for aggregate and trend questions about deals — totals per period ('sum my 2023 deals per month'), breakdowns by dimension ('deals by stage', 'deals above 10,000 broken down by partner'), and any request that ends in a chart. `group_by` selects the dimension: 'time' returns a period series ordered oldest-first (`granularity` 'month' | 'quarter' | 'year'); 'partner', 'stage' and 'pipeline' return groups ranked by total_amount; 'status' returns exactly three groups — won, lost, open — using the same stage-name rule as the `status` filter, and ignores `limit`; 'none' returns a single total bucket. `date_field` selects which date both the window and the periods are built from: 'created' (default — when the deal entered the pipeline, always populated) or 'closed' (the deal close date, which is empty on deals that are still open). `limit` caps the number of groups returned and is applied after the full set has been aggregated, so the totals of the returned groups are unaffected by it. Amounts are the sum of the deal amount field. For money actually billed and collected, `performance(action: 'company')` is the source. For partner leaderboards by revenue or deal count, `performance(action: 'overall')` ranks partners. For the individual deal rows rather than aggregates, `get_search_deals` returns the rows.
deal_analytics
[Performance & Rankings] Deal attribution for a date range: counts and totals for sourced deals (partner-originated), influenced deals (partner-touched) and deals that are both, with per-partner breakdowns suitable for ranking. Use it for deal-source-attribution questions — how many deals were sourced or influenced, their total value, sourced versus influenced comparisons, and partner rankings on either. Partner deal lists without the sourced/influenced framing are `partner_artifacts(action: 'deals')`, company-wide aggregates are `performance(action: 'overall')`, and one deal looked up by name is `get_search_deals`.
influenced_sourced_deals
[Fund Requests — Customer Admin] Decides on a Marketing Development Fund (MDF) or Co-op Investment Fund (CIF) request a partner has submitted against your company's funds. Every action needs fund_request_id and fund_request_step_id, both from customer_fund_requests(action:'get_request'). Approving completes the approval step and the request moves on to whatever comes next; rejecting ends it; request_info asks the partner for more before you decide, so the request stays open on the same step and flips to waiting on them — it is not a decision and can still be followed by approve or reject. Only a request whose current_step.type is 'customer approval' can be decided here, and only by a user configured as an approver for that step. Completion is processed in the background, so read the request back ONCE with customer_fund_requests(action:'get_request') after a short pause instead of repeating the call.
customer_fund_requests_manage
[Content Search] EULER product help and support search — THE tool for any question about how EULER itself works or how to do something in the EULER product: 'how do I add a user', 'how do I submit a referral', 'where do I find X in the portal', 'what is <EULER feature>', 'how do I set up Y'. It searches EULER's public help centre and support articles and returns the matching article text plus a citable `article_url`, and needs only the question — no partner_id or other context. Call it before telling a user that a procedure cannot be found or is undocumented, rather than guessing generic SaaS steps. Semantic search of a partner's privately-shared content is `content_search`; listing a partner's files by name is `content_list`.
euler_help
[Conversation Insights] Lists the company's own support CONVERSATIONS behind a problem area — the data behind the dashboard's trending-topics and resolution-by-category views. It is filtered by ONE problem area — a category or a trending topic — and optionally by resolution outcome and time window, and returns the matching conversations, newest classified first, each with its resolution outcome. Use it when the user asks to see, pull up or list conversations, chats or support threads about something. Each conversation also names who it is with — the user, the partner, the partner's CRM record id and which CRM that id is from, the partner company's own domain, and the company the user belongs to — null where there is no partner. totalCount is exact, and capped=true means only the first page is shown, worth saying as 'M total, showing the first N'. If available is false the lookup failed: say so and suggest trying again, never reporting zero as if it were genuine.
find_conversations_by_problem
[Flows — onboarding & training lifecycle] Reads Flows — onboarding, training and certification programmes — with their steps, assignments and attachable resources. Customer-admin actions: action='list' returns every flow the company has as {id, name, status}, newest first and with no server-side filter, so narrow the returned list yourself; it is the entry point when you have no flow_id. action='list_standard' returns the Standard Flows, the default set auto-assigned to a partner when they join the portal, as {id, flow_id, flow_name, completion_rule, status} — that `id` is the flow_standard_id flows_manage(action:'remove_standard') takes, and `status` tells an active entry from an archived one. action='flow_details' resolves exactly ONE of name (search by title), flow_id (the flow, its assignments and its step ids) or flow_step_id (that step); passing two silently drops all but the first, so drill down in separate calls. action='attachable_resources' lists the items a step can embed, and the ids it returns feed flows_manage(action:'create_or_edit_step'). action='assignment_candidates' lists the partners and users a flow can be assigned to. action='assignments' returns the company's assignment roster; action='recipient_count' is its dry run — it reports how many partners an assignment would reach (new_count) and changes nothing. Partner-role actions: action='partner_flow_details' returns the calling partner's own flows and steps; action='partner_flow_progress' returns one flow's completion stats for that partner; action='partner_team_progress' returns that partner's assignment roster with per-user completion and is admin-only, so a partner user without an admin role gets an authorization error. A flow's status is Draft (being created), Active (published), Unpublished (an Active flow taken down to edit, which is not Draft) or Archived (retired and locked: it can be neither assigned nor edited). `can_be_updated_now` on 'flow_details' says whether the steps and content can be edited, and never affects assigning. The roster actions return `results` — plus `grouped_by_partners` on 'assignments' — as comma-joined text to parse before presenting, alongside total_count, total_for_this_page and has_more; every row pairs progress_status with user_id/user_email, which is blank on an 'Any user…' assignment because that rule completes at team level. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
flows
[Flows — onboarding & training lifecycle] Creates, edits and assigns Flows and their steps (customer-admin only); reads live in `flows`. action='create_flow' creates a flow; 'save_flow' saves it and sets its status (publish, unpublish, archive); 'create_or_edit_step' and 'deactivate_step' add, edit and toggle steps; 'assign'/'unassign' attach and detach partners; 'add_standard'/'remove_standard' manage the company's Standard Flows. deactivate_step is staged: its change reaches partners already assigned only when the flow is saved. assign notifies the partners it reaches and is gated by confirm=true with a matching acknowledged_count; flows(action:'recipient_count') previews the count. add_standard is an upsert and remove_standard only archives: re-adding never duplicates and always restores. Assign and unassign never require unpublishing and work the same in Draft, Unpublished and Active. Changing an Active flow's steps or settings means saving it Unpublished, editing, then saving it Active again; that republish propagates the change to existing assignments. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
flows_manage
[Fund Requests — Customer Admin] Reads the Marketing Development Fund (MDF) and Co-op Investment Fund (CIF) requests your partners have submitted against your company's funds, plus the funds themselves. Each request row carries pending_action_from, where 'customer' means it is waiting on YOU and 'partner' means you are waiting on them; the full detail of one request adds its amounts, the ordered steps, the answers the partner submitted, your internal notes and current_step, the pending task. The normal loop is list_requests to find what is waiting on you, get_request to read the detail and the partner's answers, then customer_fund_requests_manage to approve, reject or ask for more information. Only a request whose current_step.type is 'customer approval' can be decided through the assistant; one sitting on 'customer upload', 'reimbursement' or 'assign deal to cif' is waiting on your team but has to be finished in the EULER portal.
customer_fund_requests
[Conversation Insights] Opens ONE support conversation by id (from a find_conversations_by_problem result) and returns its messages plus the resolution outcome, enough to summarise what the user asked, what happened and how it resolved. It also returns the full party behind the conversation — the user, the partner, the partner's CRM record id and which CRM it is from, the partner company's own domain, and the company the user belongs to — with the partner and CRM fields null for internal conversations. found=false means the conversation does not exist or is not part of this company: say you could not find it, and do not invent its contents. available=false means the fetch failed, which is worth saying so the user can try again.
get_conversation_detail
[Partner Relationships] Returns your company's OUTBOUND referral form — the form_id and its questions — used to send a referral TO a partner via send_outbound_referral. It is company-scoped and takes no partner_id; the per-partner INBOUND form is referrals(action: 'get_form_for_partner') instead. Call it to discover the form_id and the question list before collecting the user's answers, then pass those answers, each keyed by its question id, to send_outbound_referral.
get_outbound_form
[Partner Relationships] Artifacts linked to one partner: signed agreements (action='agreements'), affiliate links ('tracking_links'), deals, charges and invoices. Every action needs partner_id. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here. 'deals', 'charges' and 'invoices' are paginated.
partner_artifacts
[Incentives] Which partners are enrolled in which incentive, one row per active assignment, naming the partner, their current program, tier (null on Inc 1.0, whose packages have revenue ranges rather than tiers), enrolment date and commission. One page of the roster, for program-wide questions: which incentive each partner is on, partners listed by tier, tier-migration comparisons. `commission_pct` is the partner's rev share ONLY when `commission_lines` is 1; with several product-group, range or period lines it is null, because there is no single percentage — read that partner with `partner_inc2_incentives(action: 'status')` instead of guessing. A partner ABSENT from the roster has no active incentive assignment; the full partner list is `partners`. Company-wide aggregates are `incentives_summary`; one partner's benefits, campaigns and progression are `partner_inc{1,2}_incentives`.
incentives_roster
[Incentives] How the company's incentive programs are doing, per tier across both systems. Both land in one `tier_counts` list. An Inc 2.0 row ('2.0') is one tier of one program, counting ACTIVE inbound assignments on it; an Inc 1.0 row ('1.0') is one tier package with tier_name null, because packages have revenue ranges rather than tiers, counting the DISTINCT partners on the package — the number the Incentives dashboard shows. A count of 0 means the tier exists and nobody is on it, and a company runs exactly one system, so every row shares one program_version. Use it for aggregates — partners per tier, tier distribution before a migration — in ONE call, rather than paginating the roster to count. The partner-by-partner list is `incentives_roster`; one partner's detail is `partner_inc{1,2}_incentives`. The per-partner `Inc_1_results`/`Inc_2_results` fields are meaningless without a partner context.
incentives_summary
[Partner Contacts & Portal Invites] Invites one or more EXISTING partner contacts to a partner's portal in a single call, by their contact ids from `list_partner_contacts` or from `create_partner_contact`. Each invited contact gets the invitation email; a contact whose email already belongs to a Euler account gets portal access immediately, the rest on accept. Idempotent per contact — one already invited is neither duplicated nor emailed again. `invited_count` counts the contact ids submitted; the sends themselves happen in the background. Customer-side only. A partner_id belonging to another company returns an empty response with nothing created, rather than an error. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
invite_partners_to_portal
[Account Management] The accounts the user approved at consent: their own company plus every partner account they hold. Call it first to resolve a partner by name, or when the user has more than one role. Each entry has id, type ('customer' | 'partner'), name, company_id, partner_id (null for a customer), affiliate_company_name (partner only, the customer company hosting the partnership) and dashboard_url. To resolve a partner by name, match `type === 'partner'` AND `affiliate_company_name === <target>` and use that entry's `partner_id` for referrals / partner_artifacts / performance / commissions; those tools derive company_id from it, so partner_id is all you pass. `dashboard_url` is the EULER web-app URL for that account's role (customer /dashboard, partner /partners) — offer it for anything MCP does not cover, such as creating an incentive program or billing settings, rather than guessing a URL. `consent_summary.hidden_count` above zero means some of the user's accounts were left out of this session; ask them to reconnect instead of guessing at the rest. A `backend_data_issue` field, present only when zero accounts came back for a provisioned user, is a data anomaly rather than a consent problem: surface its support_email and continue with partners / performance / commissions, which read from the user's company directly.
list_accounts
[Partner Contacts & Portal Invites] Returns the contacts (people) associated with a specific partner — the COMPLETE team roster, including people who never logged into the portal, unlike `partner_users` action='list_users', which returns only the subset with an activated login. Customer-admin view only. Pair it with `create_partner_contact` to add a new person and `invite_partners_to_portal` to grant portal access, which takes the `id` values returned here. `contacts` is a comma-separated string of compact JSON objects, one per contact, and is NOT wrapped in brackets — wrap it yourself if you need a strict JSON array. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
list_partner_contacts
[Content Search] Lists the content a partner has in their Partner Portal — PDFs, documents, images, uploaded videos and external links (YouTube, Vimeo, Loom, Drive), newest first. Use it for 'what files do I have' or 'show the PDFs shared with me'. `is_downloadable: false` does NOT mean the partner cannot see the item — they may view it in the portal's Content section but not download it, so describe it and point them there instead of handing out `file_url`. The flag governs only `file_url`, the uploaded file; an external `link` is always safe to share. A `file_url` also opens only inside an authenticated portal session, so an access error on one means sending the user to the Content section, not retrying it or calling the content missing. Optional `query` matches by WHOLE WORD, case-insensitive, not by substring ('ickson' does not match 'PPTX Dickson'); omit it to list everything. Searching INSIDE the content is `content_search`. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
content_list
[Agreements] Lists your company's saved signature images (id + name), available to attach to an agreement template via agreements_manage's signature_id.
agreement_signatures
[Agreements] Looks up ONE agreement — either a reusable template ('terms': payment process and terms, frequency, net days, tier, referral criteria, checkbox disclaimer, restrict_access, and whether a company signature is on file) or a copy already sent to a partner ('instance': status, company and partner sign dates, the partner's signer name and title, the public agreement_url). Pass agreement_terms_id for a template OR agreements_id for a sent copy; if both arrive, agreement_terms_id wins. An id that does not resolve to a record owned by your company is reported as not found, which is never distinguished from it belonging to another company. Agreements a PARTNER has already signed are `partner_artifacts(action:'agreements')` — this tool covers the templates and the sending side.
agreements
[Content Management — Customer Admin] Write side of the customer-admin content library. action='create' adds a content item ('File' needs file_url from content_upload; 'Link' needs link) — every item needs at least one category_id from content_admin(action:'categories'). action='create_folder' adds a folder (FLAT, no nesting). action='add_to_folder' places or moves an existing item. action='edit' updates metadata and/or replaces the file/link — omitted fields keep their CURRENT value (the worker fetches the record first), and category_ids REPLACES the whole list when passed. action='change_visibility' / 'change_folder_visibility' set who can see an item or a folder; omitted visibility is preserved, and omitted share_with_all is preserved UNLESS visibility is explicitly changed away from 'All partners', which resets share_with_all to false (a visibility restriction always wins over a stale share_with_all — pass share_with_all explicitly to control it directly). partner_ids/tag_ids REPLACE the share list while add_partner_ids/remove_partner_ids change it incrementally (ignored when partner_ids is set). share_with_all=true exposes the content to EVERY partner and is confirmation-gated: tell the user what it means, get their agreement, then retry with confirm=true (without it the call is rejected with share_with_all_confirmation_required and nothing changes). action='delete' permanently removes a content item (and its category/folder links) — irreversible, confirmation-gated like share_with_all (rejected with delete_confirmation_required without confirm=true). action='archive_folder' hides a folder for good — also irreversible and confirmation-gated (archive_confirmation_required); the content that was inside it is NOT deleted or touched, it just loses that folder's organization. Get ids from content_admin.
content_manage
[Partner — Users & Roles] Creates and modifies a partner organisation's permission roles and assigns them to its members. action='add_user' creates team members from email addresses; 'invite_user' sends a portal invite to a member who already exists; 'create_role' and 'edit_role' define a role and the portal sections it may see, with edit_role changing only the fields passed; 'assign_roles' and 'remove_roles' change the roles of members of ONE partner, by email; 'bulk_assign_roles_cross_partner' and 'bulk_remove_roles_cross_partner' do the same across MANY partners at once, matching the role BY TITLE because role ids differ per partner; 'update_default_roles' sets the roles new members are auto-assigned. add_user and invite_user are PARTNER-ONLY: a customer-admin calling either gets a scope error, even on a partner of their own company. The role actions serve both a partner-admin managing their own team and a customer-admin managing a partner of their company — ⚠️ as a customer-admin they change the roles and portal access of people in ANOTHER company, so confirm the intent with the user first. Membership is matched by email against the partner's FULL contact roster from list_partner_contacts; partner_users(action:'list_users') returns only members with an activated portal login, and an email that is not one of the partner's contacts is silently skipped. The asynchronous writes report nothing about what they touched: add_user returns an empty affected_ids, since the contacts are created after the response (look them up with list_partner_contacts), and the cross-partner actions return only a scheduled_partners count, so a partner with no role of that title, or a contact not on its team, is skipped invisibly. Role ids come from partner_users(action:'list_roles'); category is one of Partnerships, Sales, Marketing, Finance and Support. On add_user, role_ids is assignable only by a partner admin — otherwise the call fails with admin_required and no contact is created — and a role_id from another partner lands in skipped.role_ids while the contact is still created; a duplicate email lands in skipped.emails. On assign_roles, a role_id outside partner_id fails the whole call with role_not_in_partner. target_partner_ids is named to avoid colliding with the reserved partner_ids identity field. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
manage_partner_users
[Partner Directory] Moderate your Partner Directory: approve or reject a partner's profile edit, hide or unhide a profile, flag it as featured, or set its tier. Takes one or more `profile_ids` from `partner_directory_search` (NOT partner_ids). Only profiles in YOUR directory can be changed — ids belonging to another customer are silently not matched, and the response says how many actually applied. Rejecting requires `rejection_message`, which the partner reads. 'unhide' restores the status the profile had before it was hidden, so it only works on a hidden profile; 'hide' only works on a profile that is not already hidden. The public directory is a cached JSON blob refreshed on a ~10-minute cycle, so a change is not visible on the public page immediately. The valid values for `tier` come from your directory settings and are not readable through MCP yet — an unrecognised tier is written verbatim and will show as a tier no filter offers.
partner_directory_manage
[Partners — general management] Diagnoses why access to the partner portal, or to one section of it, is blocked: which flow is gating access, with its progress, due date and locked sections, which pending agreements block access until signed, and the invitation status (invited, email status, activated). healthy=yes means nothing is blocking. A PARTNER uses it on their OWN access ('why can't I see the agreements tab?') without passing partner_id — the caller's own partner is used automatically, so do not ask the user for one. A CUSTOMER admin passes the partner_id of one of their partners ('why can't partner X see Y?', 'did partner X receive the invite?'). Pass `section` only when a specific portal area is named. Prefer it over guessing at bugs or permissions: it names the blocker and the concrete unblock step. Also reports `has_partner_manager` ('yes'/'no'): whether a partner manager is recorded. On 'yes', say they have one and to get in touch; on 'no', that none is recorded. When `has_partner_manager` is absent from the result, do not talk about a partner manager at all. Who the partner manager is comes back only when the customer company has chosen to share it with its partners: give it as returned, never guess it. `support_contacts`, when present, is who to reach for anything this tool cannot unblock.
partner_access_diagnosis
[Partners — general management] Reads the company's partner-registration applications (signups awaiting or past a decision) with the applicant's contact details and form answers. action='list' returns them newest first, paginated and filterable by status and submitted-on date range; only action='get' carries the `answers` array. Every row carries first_name, last_name, email_address, company_name, website, phone_number and country, resolved from the form's mapped questions; company_name falls back to the name typed on the application, and an absent value is null. `status` is free text; the values seen in practice are 'pending', 'creating', 'approved', 'rejected' and 'error writing to crm'. 'creating' = accepted AUTOMATICALLY: Euler wrote the record into the company's own CRM, creating NO partner and no partner contact here; the partner appears only once the CRM side converts that record and the sync brings it back. A MANUAL accept does create the partner here immediately, except on a Salesforce form that creates partners in the CRM only, which behaves like 'creating': 'approved' with no partner_id is normal there. Never report a company missing from the roster as evidence the applicant or company does not exist. Unsubmitted drafts (status 'draft') are excluded from both modes, so a status='draft' filter returns nothing — the filter, not proof there are none. Answers to deleted questions are excluded; an answer marked hidden may still be returned, so do not rely on it to withhold one. An application_id from another company returns an empty list, not an error. rejection_reasons returns `rejection_options` {id, reason} plus `reason_required`: an empty list means none are configured, while a response with NO `reason_required` field means they could not be read — read them again before rejecting. A row with `answers_unreadable: true` has null identity fields because its answers could not be read, NOT because they were left blank — say so, do not describe an empty application. Decide an application with resolve_partner_application. This payload contains personal contact data of real people.
partner_applications
[Partner Incentives] Get a partner's active Inc 1.0 incentive plan: the package name, the payout frequency, net days post payment, and the commission tiers, each with its min/max revenue range, commission percentage, flat payout and net days. Requires partner_id — the data is scoped to THAT partner, not the logged-in user. Use it when a partner asks about their own commission structure, tier package or payout terms, or when a customer admin asks about one of their partners'. found=false means this partner has no Inc 1.0 plan. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
partner_inc1_incentives
[Partner Incentives] Get a partner's Inc 2.0 incentive program — the tier they are on, the commission structure behind it, their benefits, any active boost or override campaign, and their live progress toward the next tier. Requires partner_id: the data is THAT partner's, not the logged-in user's. The commission structure has one row per product-group × revenue-range × time-period, so a partner can hold several rates at once. In 'progression', `all_tiers[]` is the catalogue of advancement rules per tier and `live_metrics[]` is the partner's progress, each row already carrying its rule, its goal, the calculated value and whether it is passing — so what a partner still needs for the next tier is the live_metrics rows whose tier_name is next_tier_name, with all_tiers covering tiers that have no live metric yet. found=false means the partner has no Inc 2.0 assignment. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
partner_inc2_incentives
[Performance & Rankings] Partner performance metrics and rankings over a date range. action='overall' ranks all partners ('top 5 partners', 'leaderboard', 'best performers') and requires page, limit, entity_key and one date axis. The axis is a real choice: `closed_from`/`closed_to` filter on when a deal closed, `created_from`/`created_to` on when it was created, and they return different partners — 'top partners in the last 90 days' and 'who closed the most' mean the close axis, which keeps a deal opened last year and closed inside the window. Send both axes only when the user asked for a combination; with no window given, default to closed_from = today − 90 days and closed_to = today. Pagination defaults page=1, limit=10. entity_key picks the ranking metric: 'revenue' for closed-won and invoiced value questions and as the default for generic ones, 'deals' only when the question is about deal count. The response echoes `applied_filters`, the filters actually applied (including `deal_stage_filter`); report those rather than what you sent, and note that `legacy_created_*` there is the creation axis under its old name. 'overall' is terminal — it returns the ranking plus aggregate metrics in one call, over deals only and with no commissions data, so follow-up partner_artifacts / commissions calls aren't necessary unless the user wants more depth. action='partner' returns one partner's metrics and needs partner_id; action='company' returns the user's own company aggregate (sales/deals/charges), customer-only. Disambiguation when the user names an entity: a name matching the user's own company (the `list_accounts` entry where `type==='customer'`) means action='company'; a name matching an `affiliate_company_name` or a partner of the company means action='partner' with that partner_id. For action='partner': partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
performance
[Dashboards — Program-wide Overview] Single-call executive snapshot of the company's partner program: total, active and pending partner counts, total and won deal counts, total revenue, and the top 100 partners ranked by revenue. Use it when the user wants a quick at-a-glance picture ('give me a program overview', 'how is our partner program doing overall', 'top performers'). Customer-side only, scoped to the caller's company automatically. It is unfiltered and lifetime-to-date — ranking by date range, or pagination, is `performance(action: 'overall')`.
get_partner_overall_stats
[Partners — general management] Reads the partner tags of the user's company (customer-admin view): the tag groups, the tags themselves, which tags a partner carries, and which partners carry one tag. A tag lives in at most one group, and a single-select group (is_multiselect=false) means a partner carries at most one of its tags — assigning one replaces the other. creation_method 'Automatic' marks a group or tag owned by the connected CRM: it can be assigned and removed here, but is created, renamed and archived in the CRM. The reverse lookup answers 'which partners are Gold?' in one paginated call instead of one call per partner. first_assigned_on is when the partner FIRST got the tag: removing a tag and assigning it again reactivates the original association, so the date does not move and there is no 'last assigned' date in the data. The tag_ids returned here are what partner_tags_manage, flows_manage(assign_to:'Partners by Tags') and invite_partners_to_portal(tags) take. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
partner_tags
[Partner — Users & Roles] Reads the users and permission roles of a partner organisation — for a partner-admin reading their OWN team, or a customer-admin reading one of their company's partners. ⚠️ The user list is NOT the partner's full team: it holds only people with an activated portal login, and most partner people are contacts who were never invited or never logged in, so a partner with hundreds of contacts can legitimately return a handful of users or none — that is correct, not a truncation, and the complete roster is `list_partner_contacts`. A role's `qty_users_assigned` counts the partner's CONTACTS, so its total is usually far larger than the user list — different populations, not expected to match. Every action requires partner_id, and you only ever see your own partner account (partner-admin) or a partner of your own company (customer-admin). partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
partner_users
[Diagnostics] Returns pong + echoes the caller's identity (user_id, company_id, partner_ids, roles). Useful for smoke-testing the auth chain.
ping
[SI Service Projects — Customer Admin] Posts a message to one SI service project's activity chat — the project's Recent Activity panel that both the customer and the partner on that project see in the portal. The message is posted as you, is visible to the other side of the project, and cannot be edited or deleted afterwards, so confirm the wording with the user first. It does not send an email or notification. Only submitted projects you can see accept a message; any other id is not found. The same text posted to the same project within 2 minutes is not posted twice. Read a project's activity, including these messages, with action='activity' on si_customer_service_projects or si_service_projects, which is also where project ids come from.
si_send_project_message
[Invoices] Queries invoices at the company level. action='list' returns invoices with filters for status, currency, date range and sort order; action='summary' returns aggregate totals by status (paid, pending, processing) — the one for 'how much was invoiced', 'total revenue' and other invoice aggregate questions.
company_invoices
[Partners — general management] Query the partners of the user's company (customer-admin view). action='list' searches partners by name (filter_name='<name>') and returns the partner_id values referrals / partner_artifacts / performance / commissions take; when the user asks about a company where they themselves hold a partner account, prefer `list_accounts` matched by affiliate_company_name. action='pending' returns partners awaiting approval. action='summary' is the canonical source for company-level partner-status and partner-count questions — 'how many partners are active?', 'partner status breakdown', 'partner totals' — and returns company-wide aggregates broken down by partner status; it is stable across a conversation, so one call is enough. A generic mention of partner status means the company's roster and belongs here; `partner_directory_search` covers the separate profile-status concept of the Partner Directory and fits only when the user names it. action='tags' lists the company's partner tags as {id, name} records — feed those ids into flows_manage(action:'assign', assign_to:'Partners by Tags', tag_ids:[...]) or invite_partners_to_portal(tags:[...]).
partners
[Partner Relationships] Query existing referrals and deal registrations. action='search' returns the company's referrals in both directions — inbound (received from partners) and outbound (sent to partners) — filtered by partner_id, date range, status and `direction`. action='for_partner' returns one partner's referrals, also in both directions, paginated. In both, each row's `approval_type` states its direction and the `total_referrals_*` fields count each side of the whole result rather than the returned page; treat those counts as authoritative. On 'for_partner' they read from the PARTNER's point of view even when a customer admin calls: 'you_submitted' is what the partner sent the company, 'sent_to_you' what the company sent the partner. action='get_form_for_partner' returns the referral form's form_id and questions[], and runs before `submit_referral`; each question's `answer_field` names the field its answer goes in, and the response's `presentation_guidance` is worth following on long forms. action='get_answers' returns one referral's submitted answers (needs approval_id, carried on every row of `search` and `for_partner`). action='rejection_reasons' lists a referral's valid rejection reasons for `resolve_referral`. partner_id comes from list_accounts (match affiliate_company_name) or partners(action: 'list', filter_name: ...); partner_directory_search returns profile_id values, which are rejected here.
referrals
[Flows — onboarding & training lifecycle] Reads quizzes and their questions (customer-admin only; a quiz attaches to a Flow step of type 'Quiz'). action='list' returns the company's quizzes; action='get' returns one quiz's settings and, when quiz_question_id is passed too, that question's detail; action='all_questions' returns a quiz's question list; action='list_categories' returns the company's quiz-question categories. action='attempts' returns a quiz's attempt records across the company's partners, optionally filtered to one partner — use it for 'how did partner X score on quiz Y' or 'who is mid-attempt'. There is no stored pass/fail: compare an attempt's score with the quiz's quiz_passing_score from action='get'. Creating and editing quizzes and questions is `quizzes_manage`.
quizzes
[Flows — onboarding & training lifecycle] Creates, edits and deletes quizzes and their questions (customer-admin only; a quiz attaches to a Flow step of type 'Quiz'). Questions are multiple-choice only, either single_choice or multiple_choice. action='create' creates an empty draft quiz and returns its id; action='save' saves quiz-level settings AND propagates pending question changes to existing and in-progress attempts; action='add_question' adds a question, action='update_question' fully replaces one — every field sent overwrites, so resend the values you want to keep — and action='delete_question' soft-deletes one; action='delete' deactivates a quiz. action='create_category', 'edit_category' and 'delete_category' manage the quiz-question categories, whose ids come from quizzes(action:'list_categories'). Adding, updating and deleting questions does not reach existing or in-progress attempts until action='save' runs: tell the user that and ask before saving, rather than saving on your own initiative. Reading quizzes and attempts is `quizzes`.
quizzes_manage
EULER ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve EULER'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 EULER alternatives on ChatGPT?
As of 2026-10-26, EULER competes with Crossbeam, Introw PRM, Nesha, Partner.io, Suger in ChatGPT Partner & Ecosystem Revenue, 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.