agentsclimarketplace

Sap ariba

Skill efeumutaslan/SAP-SKILLS/skills/sap-ariba

23 SAP development skills for Claude Code — ABAP, RAP, CAP, Fiori, BTP, HANA, S/4HANA, Integration Suite and more. Agent Skills Specification compatible.

Install
npx -y skills add efeumutaslan/SAP-SKILLS --skill sap-ariba

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

SAP Ariba procurement and sourcing skill. Use when integrating with Ariba APIs, working with cXML/PunchOut, configuring Cloud Integration Gateway (CIG), or connecting Ariba Network with S/4HANA. If the user mentions Ariba, cXML, PunchOut, procurement integration, or supplier management API, use this skill.

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

11.9 KB, as published. Nobody here has run it

SAP Ariba Procurement & Sourcing

Related Skills

  • sap-s4hana-extensibility — S/4HANA MM/procurement integration with Ariba
  • sap-event-mesh — Event-driven integration between Ariba and BTP
  • sap-security-authorization — OAuth/certificate setup for Ariba APIs

Quick Start

Choose your integration approach:

ScenarioAPI/ProtocolAuthentication
Procurement data extractAriba Open APIs (REST)OAuth 2.0 client credentials
Transactional documentscXML over HTTPSShared secret
Supplier managementAriba SOAP APIsCertificate-based
S/4HANA integrationCloud Integration Gateway (CIG)SAP Integration Suite
Custom UI extensionsAriba Custom FormsAriba Developer Portal

First API call — Procurement Reporting:

# Step 1: Get OAuth token
curl -X POST "https://api.ariba.com/v2/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id={{CLIENT_ID}}&client_secret={{CLIENT_SECRET}}"

# Step 2: Call Procurement API
curl -X GET "https://openapi.ariba.com/api/procurement-reporting/v2/prod/views/{{VIEW_ID}}" \
  -H "Authorization: Bearer {{TOKEN}}" \
  -H "apiKey: {{API_KEY}}" \
  -H "X-ARIBA-NETWORK-ID: {{AN_ID}}"

Core Concepts

Ariba Solution Architecture

ModulePurposeKey Objects
Ariba ProcurementRequisitions, POs, InvoicesRequisition, PurchaseOrder, Invoice
Ariba SourcingRFx, Auctions, ContractsSourcingProject, SourcingRequest
Ariba ContractsCLM, complianceContract, ContractWorkspace
Ariba Supplier ManagementQualification, riskSupplierRegistration, Questionnaire
Ariba NetworkB2B transactionscXML OrderRequest, InvoiceDetailRequest
Ariba Spend AnalysisSpend visibilitySpendFact, SpendCategory

API Landscape

  1. Open APIs (REST) — Reporting/analytics, paginated data extraction
  2. Operational APIs (REST) — CRUD on procurement documents
  3. SOAP APIs — Legacy supplier/sourcing integration
  4. cXML — B2B document exchange (PunchOut, OrderRequest, InvoiceDetail)
  5. CIG (Cloud Integration Gateway) — Mediated S/4HANA ↔ Ariba integration

cXML Protocol Essentials

  • Envelope: <cXML><Header> (auth) + <Request>/<Response>/<Message>
  • Authentication: SharedSecret in <Credential> element
  • PunchOut: Buyer catalog browsing on supplier site → PunchOutSetupRequestPunchOutOrderMessage
  • Document flow: OrderRequest → ConfirmationRequest → ShipNoticeRequest → InvoiceDetailRequest

Common Patterns

Pattern 1: cXML OrderRequest

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.060/cXML.dtd">
<cXML payloadID="{{PAYLOAD_ID}}" timestamp="2026-03-24T10:00:00+00:00">
  <Header>
    <From>
      <Credential domain="NetworkId">
        <Identity>{{BUYER_AN_ID}}</Identity>
      </Credential>
    </From>
    <To>
      <Credential domain="NetworkId">
        <Identity>{{SUPPLIER_AN_ID}}</Identity>
      </Credential>
    </To>
    <Sender>
      <Credential domain="NetworkId">
        <Identity>{{BUYER_AN_ID}}</Identity>
        <SharedSecret>{{SHARED_SECRET}}</SharedSecret>
      </Credential>
      <UserAgent>SAP Ariba Procurement</UserAgent>
    </Sender>
  </Header>
  <Request>
    <OrderRequest>
      <OrderRequestHeader orderID="PO-2026-001" orderDate="2026-03-24T10:00:00+00:00" type="new">
        <Total>
          <Money currency="EUR">5000.00</Money>
        </Total>
        <ShipTo>
          <Address addressID="ADDR-001">
            <Name xml:lang="en">Main Warehouse</Name>
          </Address>
        </ShipTo>
        <BillTo>
          <Address addressID="ADDR-002">
            <Name xml:lang="en">Finance Department</Name>
          </Address>
        </BillTo>
      </OrderRequestHeader>
      <ItemOut quantity="100" lineNumber="1">
        <ItemID>
          <SupplierPartID>MAT-001</SupplierPartID>
        </ItemID>
        <ItemDetail>
          <UnitPrice>
            <Money currency="EUR">50.00</Money>
          </UnitPrice>
          <Description xml:lang="en">Office Supplies</Description>
          <UnitOfMeasure>EA</UnitOfMeasure>
        </ItemDetail>
      </ItemOut>
    </OrderRequest>
  </Request>
</cXML>

Pattern 2: Open API Data Extraction with Pagination

import requests

BASE_URL = "https://openapi.ariba.com/api/procurement-reporting/v2/prod"
API_KEY = "{{API_KEY}}"
TOKEN = "{{OAUTH_TOKEN}}"
REALM = "{{REALM_NAME}}"

headers = {
    "Authorization": f"Bearer {TOKEN}",
    "apiKey": API_KEY,
    "Accept": "application/json"
}

def extract_requisitions(date_from, date_to):
    """Extract requisitions using Procurement Reporting API."""
    all_records = []
    page_token = None

    while True:
        params = {
            "realm": REALM,
            "filters": f'{{"createdDateFrom":"{date_from}","createdDateTo":"{date_to}"}}',
            "limit": 100
        }
        if page_token:
            params["pageToken"] = page_token

        resp = requests.get(
            f"{BASE_URL}/views/RequisitionLineItemFact",
            headers=headers, params=params
        )
        resp.raise_for_status()
        data = resp.json()

        all_records.extend(data.get("Records", []))
        page_token = data.get("PageToken")
        if not page_token:
            break

    return all_records

Pattern 3: PunchOut Setup Request

<cXML payloadID="{{PAYLOAD_ID}}" timestamp="2026-03-24T10:00:00+00:00">
  <Header><!-- credentials --></Header>
  <Request>
    <PunchOutSetupRequest operation="create">
      <BuyerCookie>{{SESSION_ID}}</BuyerCookie>
      <BrowserFormPost>
        <URL>https://buyer-app.example.com/punchout/return</URL>
      </BrowserFormPost>
      <SelectedItem>
        <ItemID>
          <SupplierPartID>CAT-001</SupplierPartID>
        </ItemID>
      </SelectedItem>
    </PunchOutSetupRequest>
  </Request>
</cXML>

Pattern 4: Operational API — Create Requisition

import requests

def create_requisition(token, api_key, realm, req_data):
    """Create purchase requisition via Operational API."""
    url = f"https://openapi.ariba.com/api/procurement/v3/prod/requisitions"
    headers = {
        "Authorization": f"Bearer {token}",
        "apiKey": api_key,
        "Content-Type": "application/json"
    }
    payload = {
        "realm": realm,
        "Requisition": {
            "Name": req_data["name"],
            "Requester": {"UniqueName": req_data["requester"]},
            "LineItems": [
                {
                    "Description": item["description"],
                    "Quantity": item["quantity"],
                    "UnitPrice": {"Amount": item["price"], "Currency": "EUR"},
                    "Commodity": {"UniqueName": item["commodity_code"]},
                    "DeliverTo": item["deliver_to"]
                }
                for item in req_data["items"]
            ]
        }
    }
    resp = requests.post(url, headers=headers, json=payload)
    resp.raise_for_status()
    return resp.json()

Pattern 5: CIG Integration with S/4HANA

S/4HANA MM ──► CIG Middleware ──► Ariba Network
  │                                    │
  PurchaseOrder (IDoc/OData)          OrderRequest (cXML)
  │                                    │
  GoodsReceipt ◄── ShipNotice ◄──── ShipNoticeRequest
  │                                    │
  InvoiceVerification ◄───────────── InvoiceDetailRequest

CIG Configuration Checklist:

  1. Enable CIG add-on in Ariba realm administration
  2. Configure S/4HANA connection (RFC destination or OData service)
  3. Map S/4HANA company codes to Ariba buying organizations
  4. Set up document routing rules (PO → cXML, Invoice → IDoc)
  5. Activate number range mapping (Ariba doc ID ↔ S/4HANA doc number)
  6. Test with Ariba Integration Toolkit (ITK) before go-live

Pattern 6: Supplier API — Questionnaire Response

def submit_questionnaire_response(token, api_key, realm, supplier_id, questionnaire_id, answers):
    """Submit supplier qualification questionnaire."""
    url = f"https://openapi.ariba.com/api/supplier-management/v1/prod/questionnaires/{questionnaire_id}/responses"
    headers = {
        "Authorization": f"Bearer {token}",
        "apiKey": api_key,
        "Content-Type": "application/json"
    }
    payload = {
        "realm": realm,
        "supplierId": supplier_id,
        "answers": [
            {"questionId": a["id"], "value": a["value"]}
            for a in answers
        ]
    }
    resp = requests.post(url, headers=headers, json=payload)
    resp.raise_for_status()
    return resp.json()

Error Catalog

Error / HTTP StatusMessageRoot CauseFix
401 UnauthorizedInvalid tokenOAuth token expired or wrong credentialsRefresh token; check client_id/secret
403 ForbiddenRealm access deniedAPI key not authorized for realmVerify API key ↔ realm mapping in Ariba Developer Portal
404 Not FoundView not foundWrong view name in reporting APICheck available views in API documentation
429 Too Many RequestsRate limit exceededAPI throttling (varies by endpoint)Implement exponential backoff; batch requests
500 Internal Server ErrorServer errorAriba platform issueRetry with backoff; check Ariba system status
cXML 400Parsing errorMalformed cXML or wrong DTDValidate against cXML DTD; check encoding
cXML 401Authentication failedWrong SharedSecret or domainVerify credentials in Ariba Network admin
cXML 406Not AcceptableDocument rejected by business rulesCheck Ariba transaction rules configuration
CIG sync errorDocument mapping failedMissing field mapping in CIG configReview CIG mapping rules; check mandatory fields
REALM_NOT_CONFIGUREDRealm not foundIntegration not set up for realmComplete realm setup in Ariba Developer Portal

Performance Tips

  1. Use reporting APIs for bulk data — Operational APIs are for single-document CRUD; reporting APIs handle millions of records with pagination
  2. Batch cXML documents — Use BatchOrderRequest for multiple POs in one transmission
  3. Cache OAuth tokens — Tokens are valid for 20 minutes; don't request a new token per API call
  4. Filter at API level — Use filters parameter to narrow date ranges; avoid client-side filtering
  5. Async for large extracts — Use asynchronous job API for views with >100K records
  6. CIG scheduling — Schedule CIG sync during off-peak hours; configure retry intervals for failed docs
  7. PunchOut session timeout — Default 30 min; extend via Extrinsic element if supplier catalogs are large
  8. Monitor API quotas — Each API has daily/hourly limits; track usage via response headers

Gotchas

  • Realm vs. site: API calls require realm name (e.g., mycompany-T for test), not site URL
  • cXML DTD validation: Many Ariba endpoints validate against DTD — missing optional elements can cause 406
  • API versioning: Open APIs use URL versioning (/v2/); always specify version explicitly
  • Timezone handling: cXML timestamps must include timezone offset; UTC recommended
  • CIG vs. direct integration: CIG handles transformations but adds latency; for real-time needs, use direct cXML
  • Ariba Network ID format: AN01234567890 — always 14 characters with AN prefix

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.