{"id":3267,"date":"2026-06-03T05:43:29","date_gmt":"2026-06-03T05:43:29","guid":{"rendered":"https:\/\/easypick.app\/?page_id=3267"},"modified":"2026-06-03T05:51:26","modified_gmt":"2026-06-03T05:51:26","slug":"api","status":"publish","type":"page","link":"https:\/\/www.easypick.app\/no\/api\/","title":{"rendered":"API"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"3267\" class=\"elementor elementor-3267\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4dd08d0 e-flex e-con-boxed e-con e-parent\" data-id=\"4dd08d0\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f42507a elementor-widget elementor-widget-html\" data-id=\"f42507a\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\" \/>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \/>\n<title>Easypick API \u2014 Programmatic Key Sharing for Developers<\/title>\n<meta name=\"description\" content=\"Open lockers, drop off keys and pick them up \u2014 programmatically. The Easypick API lets your software handle every key handover, automatically.\" \/>\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=JetBrains+Mono:wght@400;500;600&display=swap\" rel=\"stylesheet\">\n<style>\n  :root {\n    --orange: #F26522;\n    --orange-dark: #D8521A;\n    --orange-soft: #FFF1E8;\n    --orange-glow: rgba(242,101,34,0.18);\n    --ink: #323333;\n    --ink-2: #1B2435;\n    --muted: #5B6477;\n    --line: #E7E9EE;\n    --bg: #FFFFFF;\n    --bg-soft: #FAFAF7;\n    --code-bg: #2A2B2B;\n    --code-line: #1F2A3D;\n    --green: #2BB673;\n    --shadow-sm: 0 1px 2px rgba(14,23,38,.06), 0 2px 8px rgba(14,23,38,.04);\n    --shadow-md: 0 8px 24px rgba(14,23,38,.08), 0 2px 6px rgba(14,23,38,.04);\n    --shadow-lg: 0 24px 60px rgba(14,23,38,.14), 0 8px 16px rgba(14,23,38,.06);\n    --radius: 14px;\n    --radius-lg: 22px;\n  }\n\n  * { box-sizing: border-box; margin: 0; padding: 0; }\n  html { scroll-behavior: smooth; }\n  body {\n    color: var(--ink);\n    background: var(--bg);\n    line-height: 1.55;\n    font-weight: 400;\n    -webkit-font-smoothing: antialiased;\n    overflow-x: hidden;\n  }\n  code, pre { font-family: 'JetBrains Mono', monospace; }\n  a { color: inherit; text-decoration: none; }\n\n  .container { max-width: 1200px; margin: 0 auto; padding: 0 28px; }\n\n  \/* ---------- NAV ---------- *\/\n  nav {\n    position: sticky;\n    top: 0;\n    z-index: 50;\n    background: rgba(255,255,255,0.85);\n    backdrop-filter: saturate(180%) blur(14px);\n    -webkit-backdrop-filter: saturate(180%) blur(14px);\n    border-bottom: 1px solid var(--line);\n  }\n  .nav-inner {\n    display: flex; align-items: center; justify-content: space-between;\n    height: 70px;\n  }\n  .logo {\n    display: flex; align-items: center; gap: 12px;\n  }\n  .logo-img {\n    height: 34px;\n    width: auto;\n    display: block;\n  }\n  .footer-logo .logo-img {\n    height: 30px;\n  }\n  .logo-tag { font-size: 11px; padding: 3px 8px; border-radius: 999px; background: var(--orange-soft); color: var(--orange-dark); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; font-family: 'Soin Sans Neue', 'Avenir Next', 'Avenir', 'Nunito Sans', sans-serif; }\n  .nav-links { display: flex; gap: 34px; font-size: 15px; font-weight: 500; color: var(--ink-2); }\n  .nav-links a:hover { color: var(--orange); }\n  .nav-cta { display: flex; gap: 10px; align-items: center; }\n  @media (max-width: 800px) { .nav-links { display: none; } }\n\n  .btn {\n    display: inline-flex; align-items: center; gap: 8px;\n    padding: 12px 22px; border-radius: 999px;\n    font-weight: 600; font-size: 15px;\n    cursor: pointer; transition: all .2s ease;\n    border: none; font-family: inherit;\n  }\n  .btn-primary { background: var(--orange); color: #fff; box-shadow: 0 6px 18px var(--orange-glow); }\n  .btn-primary:hover { background: var(--orange-dark); transform: translateY(-1px); box-shadow: 0 10px 24px var(--orange-glow); }\n  .btn-ghost { background: transparent; color: var(--ink); }\n  .btn-ghost:hover { background: var(--bg-soft); }\n  .btn-outline { background: #fff; color: var(--ink); border: 1.5px solid var(--line); }\n  .btn-outline:hover { border-color: var(--ink); }\n  .btn-lg { padding: 16px 28px; font-size: 16px; }\n\n  \/* ---------- HERO ---------- *\/\n  .hero {\n    position: relative;\n    padding: 80px 0 100px;\n    overflow: hidden;\n  }\n  .hero::before {\n    content: \"\";\n    position: absolute; inset: 0;\n    background-image:\n      radial-gradient(ellipse 600px 300px at 80% -10%, var(--orange-glow), transparent 60%),\n      radial-gradient(ellipse 500px 300px at 5% 30%, rgba(242,101,34,0.08), transparent 60%);\n    pointer-events: none;\n  }\n  .hero-grid {\n    position: relative;\n    display: grid;\n    grid-template-columns: 1.05fr 1fr;\n    gap: 64px;\n    align-items: center;\n  }\n  @media (max-width: 960px) { .hero-grid { grid-template-columns: 1fr; gap: 48px; } }\n\n  .pill {\n    display: inline-flex; align-items: center; gap: 8px;\n    padding: 7px 14px; border-radius: 999px;\n    background: var(--orange-soft); color: var(--orange-dark);\n    font-size: 13px; font-weight: 600; letter-spacing: 0.01em;\n    border: 1px solid rgba(242,101,34,0.2);\n    margin-bottom: 22px;\n  }\n  .pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--orange); box-shadow: 0 0 0 3px rgba(242,101,34,0.25); animation: pulse 2s ease-in-out infinite; }\n  @keyframes pulse { 0%,100% { box-shadow: 0 0 0 3px rgba(242,101,34,0.25); } 50% { box-shadow: 0 0 0 6px rgba(242,101,34,0.05); } }\n\n  h1.hero-title {\n    font-size: clamp(40px, 5.6vw, 68px);\n    margin-bottom: 22px;\n  }\n  .hero-title .accent { color: var(--orange); position: relative; display: inline-block; }\n  .hero-title .accent::after {\n    content: \"\"; position: absolute; left: 0; right: 0; bottom: -4px; height: 8px;\n    background: var(--orange-soft); z-index: -1; border-radius: 4px;\n  }\n  .hero-sub {\n    font-size: 19px; color: var(--muted);\n    max-width: 540px; margin-bottom: 32px;\n  }\n  .hero-actions { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 28px; }\n\n  .what-is-api {\n    display: inline-flex; align-items: center; gap: 12px;\n    font-family: 'Soin Sans Neue', 'Avenir Next', 'Avenir', 'Nunito Sans', sans-serif;\n    font-size: 18px; font-weight: 800; line-height: 1.1;\n    color: var(--orange); text-decoration: none;\n    position: relative; padding-bottom: 7px; margin-bottom: 30px;\n    transition: opacity .2s ease;\n  }\n  .what-is-api:hover { opacity: 0.82; }\n  .what-is-api::after {\n    content: \"\"; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;\n    background: var(--orange); border-radius: 3px;\n  }\n\n  .hero-trust { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; font-size: 14px; color: var(--muted); }\n  .hero-trust .check { color: var(--green); font-weight: 700; }\n\n  \/* code window *\/\n  .code-window {\n    background: var(--code-bg);\n    border-radius: var(--radius-lg);\n    box-shadow: var(--shadow-lg);\n    overflow: hidden;\n    border: 1px solid #1F2A3D;\n    transform: rotate(0.4deg);\n    position: relative;\n  }\n  .code-window::before {\n    content: \"\";\n    position: absolute; inset: 0;\n    background: linear-gradient(135deg, transparent 0%, transparent 60%, rgba(242,101,34,0.06) 100%);\n    pointer-events: none;\n  }\n  .code-bar {\n    display: flex; align-items: center; gap: 8px;\n    padding: 14px 18px;\n    border-bottom: 1px solid var(--code-line);\n    background: rgba(255,255,255,0.02);\n  }\n  .code-dot { width: 12px; height: 12px; border-radius: 50%; }\n  .code-dot.r { background: #FF5F57; }\n  .code-dot.y { background: #FEBC2E; }\n  .code-dot.g { background: #28C840; }\n  .code-file { margin-left: 12px; font-size: 12px; color: #8A93A6; font-family: 'JetBrains Mono', monospace; }\n  .code-body {\n    padding: 22px 24px;\n    font-size: 13.5px;\n    line-height: 1.75;\n    color: #E2E6EE;\n    overflow-x: auto;\n  }\n  .code-body .kw { color: #FF8A4C; }\n  .code-body .str { color: #9AE6A4; }\n  .code-body .key { color: #7FC4FF; }\n  .code-body .com { color: #5B6477; font-style: italic; }\n  .code-body .num { color: #FFD580; }\n  .code-body .punct { color: #8A93A6; }\n\n  \/* ---------- LOGO STRIP ---------- *\/\n  .strip {\n    padding: 40px 0 20px;\n    border-top: 1px solid var(--line);\n    border-bottom: 1px solid var(--line);\n    background: var(--bg-soft);\n  }\n  .strip-label { text-align: center; font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); font-weight: 600; margin-bottom: 22px; }\n  .strip-grid { display: flex; justify-content: space-around; flex-wrap: wrap; gap: 30px 50px; align-items: center; padding-bottom: 30px; }\n  .strip-item { font-family: 'Soin Sans Neue', 'Avenir Next', 'Avenir', 'Nunito Sans', sans-serif; font-weight: 700; font-size: 20px; color: #98A0AE; letter-spacing: -0.01em; opacity: .8; }\n  .strip-item span { font-weight: 700; font-style: normal; }\n\n  \/* ---------- SECTION HEADERS ---------- *\/\n  section { padding: 100px 0; }\n  .section-head { text-align: center; max-width: 720px; margin: 0 auto 64px; }\n  .eyebrow {\n    display: inline-block;\n    font-size: 12px; font-weight: 700; letter-spacing: 0.18em;\n    text-transform: uppercase; color: var(--orange);\n    margin-bottom: 14px;\n  }\n  .section-head h2 { font-size: clamp(32px, 4vw, 46px); margin-bottom: 16px; }\n  .section-head h2.caps { text-transform: uppercase; }\n  .section-head p { font-size: 18px; color: var(--muted); }\n\n  \/* ---------- FEATURES GRID ---------- *\/\n  .features { background: var(--bg-soft); }\n  .feat-grid {\n    display: grid;\n    grid-template-columns: repeat(3, 1fr);\n    gap: 24px;\n  }\n  @media (max-width: 900px) { .feat-grid { grid-template-columns: 1fr 1fr; } }\n  @media (max-width: 600px) { .feat-grid { grid-template-columns: 1fr; } }\n\n  .feat-card {\n    background: #fff;\n    border: 1px solid var(--line);\n    border-radius: var(--radius-lg);\n    padding: 32px 28px;\n    transition: all .25s ease;\n    position: relative;\n    overflow: hidden;\n  }\n  .feat-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: rgba(242,101,34,0.3); }\n  .feat-card::before {\n    content: \"\"; position: absolute; top: 0; left: 0; right: 0; height: 3px;\n    background: var(--orange);\n    transform: scaleX(0); transform-origin: left;\n    transition: transform .3s ease;\n  }\n  .feat-card:hover::before { transform: scaleX(1); }\n  .feat-card h3 { font-size: 20px; margin-bottom: 10px; }\n  .feat-card h3 .n { color: var(--orange); }\n  .feat-card p { font-size: 15px; color: var(--muted); }\n\n  \/* ---------- WHAT IS API ---------- *\/\n  .what-is { background: var(--bg-soft); }\n\n  \/* ---------- USE CASES ---------- *\/\n  .usecase-grid {\n    display: grid;\n    grid-template-columns: repeat(3, 1fr);\n    gap: 24px;\n  }\n  @media (max-width: 900px) { .usecase-grid { grid-template-columns: 1fr 1fr; } }\n  @media (max-width: 640px) { .usecase-grid { grid-template-columns: 1fr; } }\n\n  .usecase {\n    border: 1px solid var(--line);\n    border-radius: var(--radius-lg);\n    padding: 36px 32px;\n    position: relative;\n    overflow: hidden;\n    background: #fff;\n    transition: all .3s ease;\n  }\n  .usecase:hover { border-color: var(--orange); transform: translateY(-2px); }\n  .usecase h3 { font-size: 21px; margin-bottom: 12px; }\n  .usecase p { color: var(--muted); font-size: 15.5px; margin-bottom: 18px; }\n  .usecase ul { list-style: none; }\n  .usecase li {\n    display: flex; align-items: flex-start; gap: 10px;\n    font-size: 14px; color: var(--ink-2); padding: 5px 0;\n  }\n  .usecase li::before {\n    content: \"\"; flex-shrink: 0; margin-top: 8px;\n    width: 6px; height: 6px; border-radius: 50%;\n    background: var(--orange);\n  }\n\n  \/* ---------- HOW IT WORKS \/ TABS ---------- *\/\n  .how { background: var(--bg-soft); position: relative; overflow: hidden; }\n\n  .how-grid { display: grid; grid-template-columns: 1fr 1.3fr; gap: 48px; align-items: start; }\n  @media (max-width: 900px) { .how-grid { grid-template-columns: 1fr; } }\n\n  .steps { display: flex; flex-direction: column; gap: 16px; }\n  .step {\n    padding: 24px 26px;\n    border-radius: var(--radius);\n    cursor: pointer;\n    border: 1px solid var(--line);\n    background: #fff;\n    box-shadow: 0 1px 2px rgba(16,24,40,0.05);\n    transition: all .2s ease;\n  }\n  .step:hover { border-color: rgba(242,101,34,0.4); }\n  .step.active {\n    background: var(--orange-soft);\n    border-color: var(--orange);\n  }\n  .step-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }\n  .step-num {\n    font-family: 'Soin Sans Neue', 'Avenir Next', 'Avenir', 'Nunito Sans', sans-serif;\n    font-size: 18px; font-weight: 700; color: var(--ink); flex-shrink: 0;\n  }\n  .step h4 { color: var(--ink); font-size: 18px; font-family: 'Soin Sans Neue', 'Avenir Next', 'Avenir', 'Nunito Sans', sans-serif; font-weight: 700; }\n  .step p { color: var(--muted); font-size: 14.5px; }\n\n  .how .code-window { transform: none; }\n  .how .code-body { font-size: 13px; }\n\n  \/* ---------- ENDPOINTS ---------- *\/\n  .endpoints-list {\n    display: grid;\n    gap: 14px;\n  }\n  .endpoint {\n    display: grid;\n    grid-template-columns: 90px 1fr auto;\n    gap: 22px;\n    align-items: center;\n    padding: 22px 28px;\n    background: #fff;\n    border: 1px solid var(--line);\n    border-radius: var(--radius);\n    transition: all .2s ease;\n  }\n  .endpoint:hover { border-color: var(--orange); box-shadow: var(--shadow-sm); transform: translateX(4px); }\n  .method {\n    font-family: 'JetBrains Mono', monospace;\n    font-size: 11px; font-weight: 700;\n    padding: 5px 10px; border-radius: 6px;\n    text-align: center;\n    letter-spacing: 0.04em;\n  }\n  .method.post { background: #E8F5EE; color: #1A8B4A; }\n  .method.get { background: #E8EFFB; color: #1A56B5; }\n  .method.del { background: #FBE8E8; color: #B51A1A; }\n  .endpoint .path { font-family: 'JetBrains Mono', monospace; font-size: 14px; color: var(--ink); }\n  .endpoint .desc { font-size: 14px; color: var(--muted); }\n  @media (max-width: 700px) {\n    .endpoint { grid-template-columns: 1fr; gap: 8px; }\n    .endpoint .desc { grid-column: 1; }\n  }\n\n  \/* ---------- INTEREST FORM ---------- *\/\n  .signup {\n    position: relative;\n    overflow: hidden;\n  }\n  .signup-card {\n    background: linear-gradient(135deg, var(--ink) 0%, #404141 100%);\n    border-radius: 28px;\n    padding: 64px 56px;\n    position: relative;\n    overflow: hidden;\n    box-shadow: var(--shadow-lg);\n  }\n  .signup-card::before {\n    content: \"\"; position: absolute;\n    top: -100px; right: -100px;\n    width: 400px; height: 400px;\n    background: radial-gradient(circle, var(--orange-glow) 0%, transparent 60%);\n    pointer-events: none;\n  }\n  .signup-card::after {\n    content: \"\"; position: absolute;\n    bottom: -50px; left: -50px;\n    width: 250px; height: 250px;\n    background: radial-gradient(circle, rgba(242,101,34,0.12) 0%, transparent 60%);\n    pointer-events: none;\n  }\n  .signup-grid { position: relative; display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }\n  @media (max-width: 900px) { .signup-grid { grid-template-columns: 1fr; gap: 40px; } .signup-card { padding: 44px 28px; } }\n\n  .signup h2 { color: #fff; font-size: clamp(30px, 4vw, 40px); margin-bottom: 16px; }\n  .signup p.lead { color: #B7BFCE; font-size: 17px; margin-bottom: 28px; }\n  .signup-bullets { list-style: none; }\n  .signup-bullets li { display: flex; align-items: center; gap: 10px; padding: 5px 0; font-size: 14px; color: #B7BFCE; }\n  .signup-bullets li::before { content: \"\"; width: 16px; height: 16px; border-radius: 50%; background: var(--orange); flex-shrink: 0; box-shadow: 0 0 0 4px rgba(242,101,34,0.15); }\n\n  .form { background: #fff; border-radius: 18px; padding: 32px; box-shadow: var(--shadow-lg); position: relative; }\n  .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 14px; }\n  .form-field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }\n  .form-field label { font-size: 13px; font-weight: 600; color: var(--ink-2); }\n  .form-field input, .form-field select, .form-field textarea {\n    border: 1.5px solid var(--line);\n    border-radius: 10px;\n    padding: 12px 14px;\n    font-size: 14px;\n    font-family: inherit;\n    color: var(--ink);\n    background: #fff;\n    transition: border-color .15s ease;\n  }\n  .form-field input:focus, .form-field select:focus, .form-field textarea:focus {\n    outline: none; border-color: var(--orange);\n    box-shadow: 0 0 0 4px var(--orange-glow);\n  }\n  .form-field textarea { resize: vertical; min-height: 80px; }\n  .form button { width: 100%; padding: 15px; font-size: 15px; }\n  .form-note { font-size: 12px; color: var(--muted); text-align: center; margin-top: 12px; }\n  @media (max-width: 500px) { .form-row { grid-template-columns: 1fr; } }\n\n  .form-success {\n    text-align: center;\n    padding: 30px 10px;\n  }\n  .form-success .check-circle {\n    width: 64px; height: 64px;\n    background: var(--orange-soft); color: var(--orange);\n    border-radius: 50%;\n    display: grid; place-items: center;\n    margin: 0 auto 18px;\n    font-size: 32px;\n  }\n  .form-success h3 { font-family: 'Soin Sans Neue', 'Avenir Next', 'Avenir', 'Nunito Sans', sans-serif; font-size: 20px; margin-bottom: 8px; }\n  .form-success p { color: var(--muted); font-size: 14px; }\n\n  \/* ---------- START BUILDING ---------- *\/\n  .get-started { background: var(--bg-soft); }\n  .access-form { max-width: 1000px; margin: 40px auto 0; }\n  .access-form .af-row { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }\n  .access-form .af-field { display: flex; flex-direction: column; gap: 9px; margin-bottom: 22px; }\n  .access-form label { font-size: 15px; font-weight: 600; color: var(--ink); }\n  .access-form .req { color: #E5484D; }\n  .access-form input {\n    width: 100%; padding: 14px 16px; font-size: 15px;\n    border: 1px solid var(--line); border-radius: 10px;\n    background: #fff; font-family: inherit; color: var(--ink);\n    box-shadow: 0 1px 2px rgba(16,24,40,0.05);\n    transition: border-color .15s ease, box-shadow .15s ease;\n  }\n  .access-form input:focus { outline: none; border-color: var(--orange); box-shadow: 0 0 0 3px var(--orange-glow); }\n  .access-form button { width: 100%; justify-content: center; padding: 16px; font-size: 16px; margin-top: 6px; }\n  @media (max-width: 600px) { .access-form .af-row { grid-template-columns: 1fr; } }\n\n  \/* ---------- FAQ ---------- *\/\n  .faq-list {\n    max-width: 880px; margin: 0 auto;\n    background: var(--bg-soft);\n    border: 1px solid var(--line);\n    border-radius: var(--radius-lg);\n    overflow: hidden;\n  }\n  details.faq-item {\n    border-bottom: 1px solid var(--line);\n    padding: 0 28px;\n  }\n  details.faq-item:last-child { border-bottom: none; }\n  details.faq-item[open] { background: #fff; }\n  details.faq-item summary {\n    cursor: pointer;\n    list-style: none;\n    display: flex; align-items: center; gap: 18px;\n    padding: 20px 0;\n    font-family: 'Soin Sans Neue', 'Avenir Next', 'Avenir', 'Nunito Sans', sans-serif;\n    font-weight: 600; font-size: 18px; color: var(--ink);\n  }\n  details.faq-item summary::-webkit-details-marker { display: none; }\n  details.faq-item summary::before {\n    content: \"+\";\n    font-size: 26px; color: var(--orange);\n    font-weight: 400; line-height: 1; flex-shrink: 0;\n    width: 20px; text-align: center;\n    transition: transform .2s ease;\n  }\n  details.faq-item[open] summary::before { transform: rotate(45deg); }\n  details.faq-item p { color: var(--muted); font-size: 15px; padding: 0 0 20px 38px; line-height: 1.65; }\n\n  \/* ---------- FOOTER ---------- *\/\n  footer {\n    background: var(--ink);\n    color: #98A0AE;\n    padding: 60px 0 30px;\n  }\n  .footer-grid {\n    display: grid;\n    grid-template-columns: 2fr 1fr 1fr 1fr;\n    gap: 40px;\n    margin-bottom: 40px;\n  }\n  @media (max-width: 800px) { .footer-grid { grid-template-columns: 1fr 1fr; } }\n  footer .logo { color: #fff; margin-bottom: 14px; }\n  footer p.about { font-size: 14px; max-width: 320px; line-height: 1.6; }\n  footer h5 { color: #fff; font-size: 13px; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 16px; font-family: 'Soin Sans Neue', 'Avenir Next', 'Avenir', 'Nunito Sans', sans-serif; font-weight: 600; }\n  footer ul { list-style: none; }\n  footer ul li { padding: 5px 0; font-size: 14px; }\n  footer ul li a:hover { color: var(--orange); }\n  .footer-bottom {\n    border-top: 1px solid #1F2A3D;\n    padding-top: 24px;\n    display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px;\n    font-size: 13px;\n  }\n\n  \/* ---------- TOP BANNER ---------- *\/\n  .top-banner { background: var(--ink); text-align: center; padding: 64px 0; }\n  .top-banner h2 {\n    color: #fff;\n    font-family: 'Soin Sans Neue', 'Avenir Next', 'Avenir', 'Nunito Sans', sans-serif;\n    font-weight: 400; font-size: clamp(30px, 4vw, 44px); letter-spacing: 0.02em;\n    text-transform: uppercase;\n    margin-bottom: 18px;\n  }\n  .top-banner p { color: var(--orange); font-size: clamp(16px, 2vw, 20px); font-weight: 600; }\n\n  \/* ---------- ENTRANCE ANIMATION ---------- *\/\n  .reveal { opacity: 0; transform: translateY(20px); transition: opacity .7s ease, transform .7s ease; }\n  .reveal.in { opacity: 1; transform: translateY(0); }\n<\/style>\n<\/head>\n<body>\n\n\n<!-- ============ TOP BANNER ============ -->\n<section class=\"top-banner\">\n  <div class=\"container\">\n    <h2>Easypick API<\/h2>\n    <p>Bring Easypick into your existing workflow.<\/p>\n  <\/div>\n<\/section>\n\n<!-- ============ HERO ============ -->\n<header class=\"hero\">\n  <div class=\"container hero-grid\">\n    <div class=\"reveal in\">\n      <h1 class=\"hero-title\">Key handovers, now an <span class=\"accent\">API call<\/span> away.<\/h1>\n      <p class=\"hero-sub\">Easypick already moves thousands of keys through our network of pick-up points across Europe. The Easypick API lets your software open lockers, drop off keys and pick them up \u2014 automating the whole process, end-to-end.<\/p>\n      <div class=\"hero-actions\">\n        <a href=\"#signup\" class=\"btn btn-primary btn-lg\">Get started with API \u2192<\/a>\n      <\/div>\n      <a href=\"#what-is-api\" class=\"what-is-api\">\u2192 What is API?<\/a>\n      <div class=\"hero-trust\">\n        <span><span class=\"check\">\u2713<\/span> No credit card<\/span>\n        <span><span class=\"check\">\u2713<\/span> REST + Webhooks<\/span>\n        <span><span class=\"check\">\u2713<\/span> Sandbox included<\/span>\n      <\/div>\n    <\/div>\n\n    <div class=\"reveal in\">\n      <div class=\"code-window\">\n        <div class=\"code-bar\">\n          <div class=\"code-dot r\"><\/div>\n          <div class=\"code-dot y\"><\/div>\n          <div class=\"code-dot g\"><\/div>\n          <span class=\"code-file\">curl \u00b7 open-locker.sh<\/span>\n        <\/div>\n<pre class=\"code-body\"><span class=\"com\"># Open a locker, programmatically<\/span>\ncurl -X POST https:\/\/api.easypick.app\/v1\/lockers\/open \\\n  -H <span class=\"str\">\"Authorization: Bearer ep_live_\u2022\u2022\u2022\u2022\"<\/span> \\\n  -H <span class=\"str\">\"Content-Type: application\/json\"<\/span> \\\n  -d <span class=\"punct\">'{<\/span>\n    <span class=\"key\">\"location_id\"<\/span>: <span class=\"str\">\"loc_oslo_central_42\"<\/span>,\n    <span class=\"key\">\"compartment\"<\/span>: <span class=\"str\">\"M12-04\"<\/span>,\n    <span class=\"key\">\"recipient\"<\/span>: <span class=\"punct\">{<\/span>\n      <span class=\"key\">\"name\"<\/span>: <span class=\"str\">\"Anna H.\"<\/span>,\n      <span class=\"key\">\"phone\"<\/span>: <span class=\"str\">\"+4798765432\"<\/span>\n    <span class=\"punct\">}<\/span>,\n    <span class=\"key\">\"valid_for_hours\"<\/span>: <span class=\"num\">48<\/span>\n  <span class=\"punct\">}'<\/span>\n\n<span class=\"com\"># \u2192 201 Created<\/span>\n<span class=\"com\"># \u2192 access_link: https:\/\/ep.app\/u\/k7Hq2x<\/span>\n<span class=\"com\"># \u2192 pickup_code: 482-019<\/span>\n<\/pre>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/header>\n\n<!-- ============ STRIP ============ -->\n<div class=\"strip\">\n  <div class=\"container\">\n    <div class=\"strip-label\">Built for the systems your business already runs on<\/div>\n    <div class=\"strip-grid\">\n      <div class=\"strip-item\">Property <span>Management<\/span><\/div>\n      <div class=\"strip-item\">Car <span>Rental<\/span><\/div>\n      <div class=\"strip-item\">Cleaning <span>Services<\/span><\/div>\n      <div class=\"strip-item\">Real <span>Estate<\/span><\/div>\n      <div class=\"strip-item\">Short-term <span>Lease<\/span><\/div>\n      <div class=\"strip-item\">Logistics<\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- ============ FEATURES ============ -->\n<section id=\"features\" class=\"features\">\n  <div class=\"container\">\n    <div class=\"section-head\">\n      <h2 class=\"caps\">Automate your workflow with API<\/h2>\n      <p>Bring Easypick into your existing workflow. Skip manual steps. Start the Easypick flow directly from your booking system, CRM, or Zapier.<\/p>\n    <\/div>\n\n    <div class=\"feat-grid\">\n      <div class=\"feat-card\">\n        <h3>Schedule ahead<\/h3>\n        <p>Pre-generate pickup codes tied to a booking, valid only between check-in and check-out. Set, forget, automate.<\/p>\n      <\/div>\n      <div class=\"feat-card\">\n        <h3>Open any locker<\/h3>\n        <p><strong>Open compartments remotely with a simple request.<\/strong> Instantly generate pickup codes or shareable links.<\/p>\n      <\/div>\n      <div class=\"feat-card\">\n        <h3>Live key tracking<\/h3>\n        <p><strong>Know exactly where every key is, every second.<\/strong> Status updates pushed straight to your service via signed webhooks.<\/p>\n      <\/div>\n      <div class=\"feat-card\">\n        <h3>Anonymous and secure<\/h3>\n        <p>Keys stay anonymous in our network. The API uses scoped tokens, signed webhooks, and audit logs out of the box.<\/p>\n      <\/div>\n      <div class=\"feat-card\">\n        <h3>Developer-first docs<\/h3>\n        <p>OpenAPI spec, SDKs for Node, Python and Go, copy-paste recipes, and a <strong>sandbox you can hammer for free.<\/strong><\/p>\n      <\/div>\n      <div class=\"feat-card\">\n        <h3>Pan-European coverage<\/h3>\n        <p>Live in Norway, Sweden, Denmark, Germany and growing. One API, every Easypick pick-up point and locker on the network.<\/p>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ============ USE CASES ============ -->\n<section>\n  <div class=\"container\">\n    <div class=\"section-head\">\n      <h2 class=\"caps\">Built for the businesses moving keys all day.<\/h2>\n      <p>If your team is texting codes or meeting guests at the door, the API was built for you.<\/p>\n    <\/div>\n\n    <div class=\"usecase-grid\">\n      <div class=\"usecase\">\n        <h3>Short-term rentals and Airbnb hosts<\/h3>\n        <p>Sync guest reservations from your PMS. Pickup codes are minted on confirmation, sent via your own messaging, expired automatically at check-out.<\/p>\n        <ul>\n          <li>Auto-generate per-booking codes<\/li>\n          <li>Webhook on every key movement<\/li>\n          <li>Works alongside Guesty, Hostaway, Lodgify<\/li>\n        <\/ul>\n      <\/div>\n\n      <div class=\"usecase\">\n        <h3>Cleaning and maintenance crews<\/h3>\n        <p>Issue time-boxed access to contractors. Revoke instantly when the job's done.<\/p>\n        <ul>\n          <li>Per-staff scoped pickup codes<\/li>\n          <li>Audit log of who accessed what and when<\/li>\n          <li>Bulk operations via the API<\/li>\n        <\/ul>\n      <\/div>\n\n      <div class=\"usecase\">\n        <h3>Real estate and property managers<\/h3>\n        <p>Schedule viewings by the hundred. Agents and prospects collect keys themselves \u2014 your office stays focused on closing deals.<\/p>\n        <ul>\n          <li>Calendar-driven access windows<\/li>\n          <li>Multi-property dashboards<\/li>\n          <li>Custom branding on pickup links<\/li>\n        <\/ul>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ============ HOW IT WORKS ============ -->\n<section id=\"how\" class=\"how\">\n  <div class=\"container\">\n    <div class=\"section-head\">\n      <h2 class=\"caps\">Slik fungerer det<\/h2>\n      <p>Four steps. Zero counter time. From the booking event to the door \u2014 entirely on autopilot.<\/p>\n    <\/div>\n\n    <div class=\"how-grid\">\n      <div class=\"steps\">\n        <div class=\"step active\" data-step=\"1\">\n          <div class=\"step-head\"><div class=\"step-num\">1.<\/div><h4>Authenticate<\/h4><\/div>\n          <p>Get an API key from the dashboard. Use it as a bearer token on every call.<\/p>\n        <\/div>\n        <div class=\"step\" data-step=\"2\">\n          <div class=\"step-head\"><div class=\"step-num\">2.<\/div><h4>Create a key handover<\/h4><\/div>\n          <p>POST a location, compartment and recipient. We mint a pickup code and a shareable link.<\/p>\n        <\/div>\n        <div class=\"step\" data-step=\"3\">\n          <div class=\"step-head\"><div class=\"step-num\">3.<\/div><h4>Send the link to your user<\/h4><\/div>\n          <p>The recipient opens the link, taps Open, and the locker pops open. No app install required.<\/p>\n        <\/div>\n        <div class=\"step\" data-step=\"4\">\n          <div class=\"step-head\"><div class=\"step-num\">4.<\/div><h4>Get notified, stay in sync<\/h4><\/div>\n          <p>Webhooks fire on every state change: created, opened, picked up, expired, returned.<\/p>\n        <\/div>\n      <\/div>\n\n      <div class=\"code-window\">\n        <div class=\"code-bar\">\n          <div class=\"code-dot r\"><\/div>\n          <div class=\"code-dot y\"><\/div>\n          <div class=\"code-dot g\"><\/div>\n          <span class=\"code-file\" id=\"code-file\">step1.js \u00b7 authenticate<\/span>\n        <\/div>\n        <pre class=\"code-body\" id=\"code-body\"><\/pre>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ============ ENDPOINTS ============ -->\n<section id=\"endpoints\">\n  <div class=\"container\">\n    <div class=\"section-head\">\n      <h2>REST API<\/h2>\n      <p>A small surface, full coverage. No bloat. Just the verbs your team actually needs.<\/p>\n    <\/div>\n\n    <div class=\"endpoints-list\" style=\"max-width: 920px; margin: 0 auto;\">\n      <div class=\"endpoint\">\n        <div class=\"method post\">POST<\/div>\n        <div class=\"path\">\/v1\/lockers\/open<\/div>\n        <div class=\"desc\">Open a compartment &amp; mint a pickup link<\/div>\n      <\/div>\n      <div class=\"endpoint\">\n        <div class=\"method post\">POST<\/div>\n        <div class=\"path\">\/v1\/handovers<\/div>\n        <div class=\"desc\">Schedule a key drop-off \/ pick-up window<\/div>\n      <\/div>\n      <div class=\"endpoint\">\n        <div class=\"method get\">GET<\/div>\n        <div class=\"path\">\/v1\/handovers\/{id}<\/div>\n        <div class=\"desc\">Fetch live status of a handover<\/div>\n      <\/div>\n      <div class=\"endpoint\">\n        <div class=\"method get\">GET<\/div>\n        <div class=\"path\">\/v1\/locations<\/div>\n        <div class=\"desc\">List every Easypick point you can use<\/div>\n      <\/div>\n      <div class=\"endpoint\">\n        <div class=\"method get\">GET<\/div>\n        <div class=\"path\">\/v1\/keys<\/div>\n        <div class=\"desc\">List keys, chips and current locations<\/div>\n      <\/div>\n      <div class=\"endpoint\">\n        <div class=\"method post\">POST<\/div>\n        <div class=\"path\">\/v1\/webhooks<\/div>\n        <div class=\"desc\">Register a signed webhook endpoint<\/div>\n      <\/div>\n      <div class=\"endpoint\">\n        <div class=\"method del\">DEL<\/div>\n        <div class=\"path\">\/v1\/handovers\/{id}<\/div>\n        <div class=\"desc\">Revoke an active pickup code instantly<\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ============ WHAT IS API ============ -->\n<section id=\"what-is-api\" class=\"what-is\">\n  <div class=\"container\">\n    <div class=\"section-head\">\n      <h2 class=\"caps\">What is API?<\/h2>\n      <p>API \u2014 Application Programming Interface are mechanisms that enable software components to communicate with each other using a set of definitions and protocols.<\/p>\n    <\/div>\n\n    <div class=\"feat-grid\">\n      <div class=\"feat-card\">\n        <h3><span class=\"n\">1.<\/span> Integration<\/h3>\n        <p>The Easypick API integrates Easypick key sharing with the software you use.<\/p>\n      <\/div>\n      <div class=\"feat-card\">\n        <h3><span class=\"n\">2.<\/span> Expansion<\/h3>\n        <p>The Easypick API offers a unique opportunity to meet client needs across different platforms.<\/p>\n      <\/div>\n      <div class=\"feat-card\">\n        <h3><span class=\"n\">3.<\/span> Ease of maintenance<\/h3>\n        <p>The Easypick API acts as a gateway between your systems, connecting Easypick with the software you use and automating the process.<\/p>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ============ FAQ ============ -->\n<section id=\"faq\">\n  <div class=\"container\">\n    <div class=\"section-head\">\n      <h2>FAQ<\/h2>\n      <p>Questions, answered.<\/p>\n    <\/div>\n\n    <div class=\"faq-list\">\n      <details class=\"faq-item\" open>\n        <summary>When will the API be available?<\/summary>\n        <p>The Easypick API is in private beta right now. Selected partners are getting access in waves throughout 2026 \u2014 request access below and we'll get back to you within a few business days.<\/p>\n      <\/details>\n      <details class=\"faq-item\">\n        <summary>Do my customers need the Easypick app?<\/summary>\n        <p>No. The whole point of the API is that your customers stay in your product. They receive a web link or a 6-digit code, walk up to the locker, and they're in. No download required.<\/p>\n      <\/details>\n      <details class=\"faq-item\">\n        <summary>Which locations are supported?<\/summary>\n        <p>Every Easypick pick-up point and self-service locker on the network \u2014 currently across Norway, Sweden, Denmark and Germany, with new countries coming online regularly. The <code>\/v1\/locations<\/code> endpoint always returns the live list.<\/p>\n      <\/details>\n      <details class=\"faq-item\">\n        <summary>How are webhooks secured?<\/summary>\n        <p>Every webhook payload is signed with HMAC-SHA256 using a secret unique to your account. We also support IP allow-listing and automatic retries with exponential backoff.<\/p>\n      <\/details>\n      <details class=\"faq-item\">\n        <summary>Can I white-label the pickup pages?<\/summary>\n        <p>Yes, on the Growth and Enterprise plans. You can customize colors, logo and copy on the page your customer sees when they tap their pickup link.<\/p>\n      <\/details>\n      <details class=\"faq-item\">\n        <summary>Do you have SDKs?<\/summary>\n        <p>Official SDKs for Node.js, Python and Go ship at launch. Beta partners get the npm\/pip packages and TypeScript types straight away.<\/p>\n      <\/details>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ============ START BUILDING ============ -->\n<section id=\"signup\" class=\"get-started\">\n  <div class=\"container\">\n    <div class=\"section-head\">\n      <h2>Start building with the Easypick API<\/h2>\n      <p>Automate handovers and streamline your workflow. Request access and get pricing tailored to your volume.<\/p>\n    <\/div>\n\n    <form class=\"access-form\" id=\"access-form\" action=\"https:\/\/formsubmit.co\/support@easypick.no\" method=\"POST\" novalidate>\n      <input type=\"hidden\" name=\"_subject\" value=\"New Easypick API access request\">\n      <input type=\"hidden\" name=\"_template\" value=\"table\">\n      <input type=\"hidden\" name=\"_captcha\" value=\"false\">\n      <!-- honeypot: bots fill this, humans don't -->\n      <input type=\"text\" name=\"_honey\" tabindex=\"-1\" autocomplete=\"off\" style=\"position:absolute;left:-9999px;\" aria-hidden=\"true\">\n      <div class=\"af-row\">\n        <div class=\"af-field\">\n          <label for=\"af-name\">Fullt navn <span class=\"req\">*<\/span><\/label>\n          <input id=\"af-name\" name=\"name\" type=\"text\" required>\n        <\/div>\n        <div class=\"af-field\">\n          <label for=\"af-company\">Name of Company <span class=\"req\">*<\/span><\/label>\n          <input id=\"af-company\" name=\"company\" type=\"text\" required>\n        <\/div>\n      <\/div>\n      <div class=\"af-field\">\n        <label for=\"af-email\">E-post <span class=\"req\">*<\/span><\/label>\n        <input id=\"af-email\" name=\"email\" type=\"email\" required>\n      <\/div>\n      <div class=\"af-field\">\n        <label for=\"af-phone\">Phone number <span class=\"req\">*<\/span><\/label>\n        <input id=\"af-phone\" name=\"phone\" type=\"tel\" required>\n      <\/div>\n      <button type=\"submit\" class=\"btn btn-primary btn-lg\">Request access<\/button>\n    <\/form>\n  <\/div>\n<\/section>\n\n<!-- ============ FOOTER ============ -->\n\n\n<script>\n  \/\/ ---- step tabs in How section ----\n  const codeSamples = {\n    \"1\": {\n      file: \"step1.js \u00b7 authenticate\",\n      html: `<span class=\"kw\">import<\/span> <span class=\"punct\">{<\/span> Easypick <span class=\"punct\">}<\/span> <span class=\"kw\">from<\/span> <span class=\"str\">\"@easypick\/sdk\"<\/span><span class=\"punct\">;<\/span>\n\n<span class=\"kw\">const<\/span> ep <span class=\"punct\">=<\/span> <span class=\"kw\">new<\/span> <span class=\"key\">Easypick<\/span><span class=\"punct\">({<\/span>\n  apiKey<span class=\"punct\">:<\/span> process<span class=\"punct\">.<\/span>env<span class=\"punct\">.<\/span>EASYPICK_KEY<span class=\"punct\">,<\/span>\n  environment<span class=\"punct\">:<\/span> <span class=\"str\">\"live\"<\/span>\n<span class=\"punct\">});<\/span>\n\n<span class=\"com\">\/\/ You're authenticated. That's it.<\/span>`\n    },\n    \"2\": {\n      file: \"step2.js \u00b7 create handover\",\n      html: `<span class=\"kw\">const<\/span> handover <span class=\"punct\">=<\/span> <span class=\"kw\">await<\/span> ep<span class=\"punct\">.<\/span>handovers<span class=\"punct\">.<\/span><span class=\"key\">create<\/span><span class=\"punct\">({<\/span>\n  location_id<span class=\"punct\">:<\/span> <span class=\"str\">\"loc_oslo_central_42\"<\/span><span class=\"punct\">,<\/span>\n  type<span class=\"punct\">:<\/span> <span class=\"str\">\"locker\"<\/span><span class=\"punct\">,<\/span>\n  recipient<span class=\"punct\">:<\/span> <span class=\"punct\">{<\/span>\n    name<span class=\"punct\">:<\/span> <span class=\"str\">\"Anna H.\"<\/span><span class=\"punct\">,<\/span>\n    phone<span class=\"punct\">:<\/span> <span class=\"str\">\"+4798765432\"<\/span>\n  <span class=\"punct\">},<\/span>\n  valid_for_hours<span class=\"punct\">:<\/span> <span class=\"num\">48<\/span>\n<span class=\"punct\">});<\/span>\n\nconsole<span class=\"punct\">.<\/span><span class=\"key\">log<\/span><span class=\"punct\">(<\/span>handover<span class=\"punct\">.<\/span>access_link<span class=\"punct\">);<\/span>\n<span class=\"com\">\/\/ \u2192 https:\/\/ep.app\/u\/k7Hq2x<\/span>`\n    },\n    \"3\": {\n      file: \"step3.js \u00b7 share link\",\n      html: `<span class=\"com\">\/\/ Send the link through *your* channel.<\/span>\n<span class=\"com\">\/\/ SMS, email, in-app, your message bot \u2014<\/span>\n<span class=\"com\">\/\/ the recipient never leaves your product.<\/span>\n\n<span class=\"kw\">await<\/span> myMessenger<span class=\"punct\">.<\/span><span class=\"key\">sendSMS<\/span><span class=\"punct\">({<\/span>\n  to<span class=\"punct\">:<\/span> guest<span class=\"punct\">.<\/span>phone<span class=\"punct\">,<\/span>\n  body<span class=\"punct\">:<\/span> <span class=\"str\">\\`Welcome! Your keys: \\${handover.access_link}\\`<\/span>\n<span class=\"punct\">});<\/span>`\n    },\n    \"4\": {\n      file: \"step4.js \u00b7 webhook handler\",\n      html: `app<span class=\"punct\">.<\/span><span class=\"key\">post<\/span><span class=\"punct\">(<\/span><span class=\"str\">\"\/webhooks\/easypick\"<\/span><span class=\"punct\">,<\/span> <span class=\"punct\">(<\/span>req<span class=\"punct\">,<\/span> res<span class=\"punct\">)<\/span> <span class=\"punct\">=&gt;<\/span> <span class=\"punct\">{<\/span>\n  <span class=\"kw\">const<\/span> event <span class=\"punct\">=<\/span> ep<span class=\"punct\">.<\/span>webhooks<span class=\"punct\">.<\/span><span class=\"key\">verify<\/span><span class=\"punct\">(<\/span>req<span class=\"punct\">);<\/span>\n\n  <span class=\"kw\">switch<\/span> <span class=\"punct\">(<\/span>event<span class=\"punct\">.<\/span>type<span class=\"punct\">)<\/span> <span class=\"punct\">{<\/span>\n    <span class=\"kw\">case<\/span> <span class=\"str\">\"handover.picked_up\"<\/span><span class=\"punct\">:<\/span>\n      markBookingChecked<span class=\"key\">In<\/span><span class=\"punct\">(<\/span>event<span class=\"punct\">.<\/span>data<span class=\"punct\">.<\/span>id<span class=\"punct\">);<\/span>\n      <span class=\"kw\">break<\/span><span class=\"punct\">;<\/span>\n    <span class=\"kw\">case<\/span> <span class=\"str\">\"handover.expired\"<\/span><span class=\"punct\">:<\/span>\n      <span class=\"key\">notifyOps<\/span><span class=\"punct\">(<\/span>event<span class=\"punct\">.<\/span>data<span class=\"punct\">);<\/span>\n      <span class=\"kw\">break<\/span><span class=\"punct\">;<\/span>\n  <span class=\"punct\">}<\/span>\n  res<span class=\"punct\">.<\/span><span class=\"key\">sendStatus<\/span><span class=\"punct\">(<\/span><span class=\"num\">200<\/span><span class=\"punct\">);<\/span>\n<span class=\"punct\">});<\/span>`\n    }\n  };\n\n  const codeBody = document.getElementById(\"code-body\");\n  const codeFile = document.getElementById(\"code-file\");\n  function showStep(n) {\n    codeBody.innerHTML = codeSamples[n].html;\n    codeFile.textContent = codeSamples[n].file;\n    document.querySelectorAll(\".step\").forEach(s => s.classList.toggle(\"active\", s.dataset.step === n));\n  }\n  document.querySelectorAll(\".step\").forEach(s => s.addEventListener(\"click\", () => showStep(s.dataset.step)));\n  showStep(\"1\");\n\n  \/\/ ---- access form submit (sends to support@easypick.no via FormSubmit) ----\n  const accessForm = document.getElementById(\"access-form\");\n  accessForm.addEventListener(\"submit\", async (e) => {\n    e.preventDefault();\n    const required = accessForm.querySelectorAll(\"[required]\");\n    let ok = true;\n    required.forEach(f => { if (!f.value.trim()) { ok = false; f.style.borderColor = \"#E55\"; } });\n    if (!ok) return;\n\n    const btn = accessForm.querySelector(\"button[type=submit]\");\n    const btnText = btn.textContent;\n    btn.disabled = true;\n    btn.textContent = \"Sending\u2026\";\n\n    try {\n      const res = await fetch(\"https:\/\/formsubmit.co\/ajax\/support@easypick.no\", {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application\/json\", \"Accept\": \"application\/json\" },\n        body: JSON.stringify(Object.fromEntries(new FormData(accessForm)))\n      });\n      if (!res.ok) throw new Error(\"Request failed\");\n      accessForm.innerHTML = `<div class=\"form-success\">\n          <div class=\"check-circle\">\u2713<\/div>\n          <h3>Request received.<\/h3>\n          <p>We'll be in touch within a few business days with API access and pricing.<\/p>\n        <\/div>`;\n    } catch (err) {\n      btn.disabled = false;\n      btn.textContent = btnText;\n      alert(\"Sorry, something went wrong sending your request. Please email support@easypick.no directly.\");\n    }\n  });\n\n  \/\/ ---- reveal-on-scroll ----\n  const io = new IntersectionObserver((entries) => {\n    entries.forEach(e => { if (e.isIntersecting) e.target.classList.add(\"in\"); });\n  }, { threshold: 0.12 });\n  document.querySelectorAll(\".feat-card, .usecase, .endpoint, .section-head\").forEach(el => {\n    el.classList.add(\"reveal\");\n    io.observe(el);\n  });\n<\/script>\n<\/body>\n<\/html>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>Easypick API \u2014 Programmatic Key Sharing for Developers Easypick API Bring Easypick into your existing workflow. Key handovers, now an API call away. Easypick already moves thousands of keys through our network of pick-up points across Europe. The Easypick API lets your software open lockers, drop off keys and pick them up \u2014 automating the [&hellip;]<\/p>","protected":false},"author":7,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-3267","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.easypick.app\/no\/wp-json\/wp\/v2\/pages\/3267","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.easypick.app\/no\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.easypick.app\/no\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.easypick.app\/no\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.easypick.app\/no\/wp-json\/wp\/v2\/comments?post=3267"}],"version-history":[{"count":7,"href":"https:\/\/www.easypick.app\/no\/wp-json\/wp\/v2\/pages\/3267\/revisions"}],"predecessor-version":[{"id":3275,"href":"https:\/\/www.easypick.app\/no\/wp-json\/wp\/v2\/pages\/3267\/revisions\/3275"}],"wp:attachment":[{"href":"https:\/\/www.easypick.app\/no\/wp-json\/wp\/v2\/media?parent=3267"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}