Jobs feed specification for ATS

Accepted formats (Joonow XML, Indeed and LinkedIn), every field with an example, reading and closing rules and best practices for your ATS jobs feed.

18 min read Markdown version

In this article
  1. Summary
  2. Accepted formats
  3. Joonow XML
  4. Indeed XML
  5. LinkedIn XML
  6. How we read the feed
  7. Job lifecycle
  8. Safety valve
  9. Confidential company
  10. Salary
  11. Location and language
  12. Applying
  13. Quality and review
  14. Best practices for jobs to look good
  15. Applications by webhook
  16. How to request the integration

This is Joonow's public jobs feed specification for applicant tracking systems (ATS) and career sites. With it you build the feed, check it in the validator and request the integration without talking to anyone. The program is free: see what your ATS gets.

Summary

  • One XML file at a public URL, ideally with https://, with all of your clients' open jobs.
  • Each job needs a stable id, title, description, apply URL and company.
  • Recommended: the email of the person responsible for the job (email). It never shows on the site and moves the job up in the ranking (why include it).
  • Recommended: the company's website and logo (companyurl, companylogo); the description (companydescription) is optional. The logo shows on the jobs, in search and in the directory, and all three help build the company page (why include them).
  • We read the feed every 6 hours (the schedule is agreed on approval), with a conditional GET (ETag and Last-Modified).
  • A job that leaves the file is closed on the second read in a row without it.
  • Applications happen on your site: the button takes people to the job URL with utm_source=joonow. Or, with applications by webhook turned on, candidates apply on Joonow and the signed application reaches your system.
  • Before requesting, validate in the validator: it shows each job's errors and stores nothing.

Accepted formats

Format When to use it Element for each job
Joonow XML (recommended) You are building the feed now or already generate the Indeed XML. <job>
Indeed XML Your ATS already publishes the standard Indeed XML (requisitionid, sourcename, remotetype). <job>
LinkedIn XML Your ATS already generates the LinkedIn jobs XML (partnerJobId, applyUrl). <job>

All three use a <source> root with a list of <job> elements. Element names are case-insensitive and text can come inside CDATA.

Joonow XML

It is the XML many ATS already generate for Indeed, with a few extra fields (expiration, hybrid model and level). Download the example XML and the XSD schema.

<?xml version="1.0" encoding="UTF-8"?>
<source>
  <publisher>Your ATS name</publisher>
  <publisherurl>https://www.your-ats.com</publisherurl>
  <lastBuildDate>2026-10-30T09:00:00Z</lastBuildDate>
  <job>
    <referencenumber>ACME-4821</referencenumber>
    <title><![CDATA[Junior Support Analyst]]></title>
    <company><![CDATA[Acme Logistics]]></company>
    <email>recruiting@acme.example</email>
    <companyurl>https://www.acme.example/</companyurl>
    <companylogo>https://www.acme.example/img/logo-acme-256.png</companylogo>
    <companydescription><![CDATA[Logistics operator with warehouses in Pernambuco and Bahia.]]></companydescription>
    <url><![CDATA[https://acme.your-ats.com/jobs/4821]]></url>
    <date>2026-10-28T13:00:00Z</date>
    <expirationdate>2026-12-15T23:59:59Z</expirationdate>
    <city><![CDATA[Austin]]></city>
    <state>TX</state>
    <country>US</country>
    <description><![CDATA[<p>Customer support...</p><h3>Requirements</h3><ul><li>...</li></ul>]]></description>
    <salary><![CDATA[US$ 3800 to US$ 4200 per month]]></salary>
    <jobtype>fulltime</jobtype>
    <category>Professional</category>
    <remotetype>Hybrid remote</remotetype>
  </job>
</source>

Job fields

Element Required Type Example How Joonow uses it
referencenumber Yes Text, up to 200 characters ACME-4821 Identifies the job from one read to the next. It must be unique and stable: if it changes, it becomes a different job. Without it, we use the apply URL.
title Yes Text, up to 200 characters Junior Support Analyst Job title, in search and on the page. An ALL CAPS title becomes normal case (acronyms stay).
description Yes Simple HTML, up to 50 KB <p>…</p><ul><li>…</li></ul> Job description. Only p, br, ul, ol, li, strong, b, em, i, u, h2, h3, h4, a, blockquote and hr are kept; everything else (scripts, styles, images) is removed.
url Yes https:// URL https://acme.your-ats.com/jobs/4821 Destination of the "Apply" button, with utm_source=joonow. It must open the job itself.
company Yes Text Acme Logistics Company name: it creates the company page with all its jobs. Empty becomes "Confidential".
city Recommended Text Austin City: filters, location search and city pages.
state Recommended Code or name TX State or region. In Brazil, the state code (UF) or the full name.
country Recommended 2-letter ISO code or name US Country. Empty uses the feed's default country, set on approval.
date Recommended Date (ISO 8601 or RFC 1123) 2026-10-28T13:00:00Z Posting date: sorting, "posted X days ago" and the job's age. Without it, we use the read date; a future date becomes today.
email Recommended Email, up to 254 characters recruiting@acme.example Work email of the person responsible for the job. It never shows on the site. The job gets ranking points and, if it gets reported, the Joonow team has someone to talk to (why include it). An invalid one is ignored, without rejecting the job.
companyurl Recommended Absolute URL https://www.acme.example/ The company's own website (not the ATS, a social profile or a jobs page). It becomes the link on the company page and helps us find the logo and social profiles (why include them).
companylogo Recommended Absolute image URL https://www.acme.example/img/logo.png Company logo in PNG, JPEG or WebP, 128 px or larger (square works best). Joonow downloads a copy and serves it from its own site.
companydescription Optional Text or simple HTML, up to 4,000 characters Logistics operator with warehouses in the Northeast. What the company does, for its page. Repeat the same text on all of the company's jobs.
expirationdate Optional Date (ISO 8601) 2026-12-15T23:59:59Z Expiration: after it, the job is closed. A job that arrives already expired is rejected.
salary Optional Text with an amount or range US$ 3800 to US$ 4200 per month Salary, only when the employer discloses it. We recognize currency (R$, US$, €), ranges and period (hour, day, week, month, year).
jobtype Optional Code fulltime Contract type (values below).
category Optional Code Professional Job level (values below). Other values are ignored.
isRemote Optional Yes or No Yes Yes = fully remote; No = on-site.
remotetype Optional Text Hybrid remote Fully remote = fully remote; Hybrid remote = hybrid. Used when isRemote is absent.

The root's publisher, publisherurl and lastBuildDate elements are optional: they help identify the file but do not change the jobs.

Why include the job owner's email

The email element (posterEmail in the LinkedIn XML) is the work email of whoever is responsible for the job: the recruiter or the employer's HR team mailbox. It is optional, but worth it:

  • The job ranks higher. The email adds points to the listing's quality score, like the salary and a complete description, and that score breaks ties among the jobs that match a search: with the email, the job moves ahead of equivalent ones without it. Showing up earlier usually brings more views and more applications.
  • There is someone to talk to before the job comes down. When the job is reported for something that can be fixed (wrong details, a swapped link), the Joonow team writes to that email before deciding whether to take it down.
  • The email stays with the Joonow team. It never appears on the job, in search, in the API or to candidates, it is not sold or used for marketing, and it is deleted 30 days after the job comes down (privacy policy).

Send one complete address per job (recruiting@company.com). "No-reply" mailboxes don't count. An invalid email is ignored without rejecting the job (it goes live without the point), and the validator shows how many jobs include the email.

Why include the company website, logo and description

companyurl, companylogo and companydescription build the page of each client company on Joonow, with the same value on all of its jobs:

  • The logo shows everywhere: on the job card, in search, on the open job and in the company directory, and it goes into the job's JSON-LD for Google.
  • They help build the company page: the website becomes the page's link once checked, the social profiles come from it, and the description goes, together with the company's own website, into the short text we write about it (we never publish the description as it came).
  • None of this changes the job: website, logo and description belong to the company. A new logo doesn't rewrite the jobs, and an invalid value is ignored without rejecting the job.

The logo is downloaded once and served by Joonow (we never load images from your server on the page). If the company claims its page, what it writes replaces what came in the feed. The validator shows how many jobs include the logo and the website.

Accepted values

jobtype (contract type): fulltime (permanent, full time), parttime (part time), contract (contractor, freelancer), temporary (temporary), internship (internship) and volunteer (volunteer). The Brazilian Portuguese labels are accepted too: Efetivo – CLT, Estatutário, Estágio, Prestador de Serviços - PJ, Freelancer, Autônomo, Cooperado, Temporário, Tempo Determinado and Intermitente.

category (level): the codes Apprentice, Intern, Entry (early career), Operational, Professional, Management (coordination and management) and Executive (leadership), or the Portuguese labels Aprendiz, Estágio, Trainee, Operacional, Profissional, Supervisão/Coordenação and Gerencial e Executivos.

Work model: isRemote with Yes or No, or remotetype with Fully remote, Hybrid remote or On-site. "COVID-19" (only temporarily remote) gets no work model.

What not to use

Our reader understands the priority element for compatibility, but it is not part of the program: sponsored jobs are not arranged through the feed. phone and internal ATS fields are ignored. Apart from the email of the person responsible for the job, do not send personal data in the feed (never candidate data).

Indeed XML

If your ATS already publishes the standard Indeed XML, choose "Indeed XML" in the validator. The differences from Joonow XML:

  • the id can come in referencenumber or requisitionid;
  • the company can come in company or sourcename;
  • jobtype in English (fulltime, parttime, contract, temporary, internship, volunteer, per diem);
  • remotetype with Fully remote or Hybrid remote;
  • email is read as the email of the person responsible for the job, used as in Joonow XML (why include it);
  • category and experience are ignored.

LinkedIn XML

If your ATS already generates the LinkedIn jobs XML, choose "LinkedIn XML". We read:

Element Use
partnerJobId Stable job id
title, description, applyUrl Title, description and apply URL
company, companyId Company; the group's companyId together with the name separates each brand
city, state, country Location
listDate, expirationDate Posting and expiration
salaries/salary/lowEnd/amount, highEnd/amount, currencyCode, period Structured salary (HOURLY, DAILY, WEEKLY, MONTHLY, YEARLY)
jobType FULL_TIME, PART_TIME, CONTRACT, TEMPORARY, INTERNSHIP, VOLUNTEER
experienceLevel INTERNSHIP, ENTRY_LEVEL, ASSOCIATE, MID_SENIOR_LEVEL, DIRECTOR, EXECUTIVE
workplaceTypes On-site, Hybrid or Remote
posterEmail Email of the person responsible for the job, used like email in Joonow XML (why include it)

How we read the feed

  • Frequency: every 6 hours by default. The schedule is agreed on approval, and the partner dashboard has a "Request a read now" button.
  • Conditional GET: we send If-None-Match and If-Modified-Since with the previous read's ETag and Last-Modified. A 304 response ends the read without downloading anything; a file identical to the previous one also stores nothing.
  • Compression: use HTTP compression (Content-Encoding: gzip, deflate or br). A downloadable .gz file is not accepted.
  • Size: up to 2 GB uncompressed and 15 minutes of download.
  • Address: a public URL, http or https (prefer https), up to 5 redirects. Internal network addresses are blocked.
  • Robot: JoonowFeedBot/1.0 (+https://www.joonow.com/robots.txt). If you have a firewall, allow this User-Agent.
  • XML: UTF-8, without <!DOCTYPE> or external entities. A file with a DTD is rejected for security reasons.

Job lifecycle

  1. New: it goes in on the next read and shows up on the site within minutes.
  2. Changed: we update it when the job's content changes (title, description, location, salary, dates…).
  3. Closed: when it is missing from the file in two reads in a row, when its expiration (expirationdate) passes, or when the apply link is down in two checks 24 hours apart.
  4. Maximum age: a job that is never renewed (its date never moves forward) is closed after 60 days; no job stays live for more than 180 days. To keep a job, republish it with a new date.
  5. After closing: the page shows "job closed" with similar jobs and, after 30 days, answers 410 to search engines.

Always send the complete inventory on every read: a partial file closes the jobs that were left out.

Safety valve

So that a broken feed does not take down your clients' jobs, the read is quarantined when:

  • more than 5% of the records are rejected; or
  • the number of valid jobs drops more than 30% compared to the previous read (with 50 jobs or more).

In quarantine nothing is published or closed, and the partner dashboard shows why. Fix the file and request a new read.

Confidential company

A job without company shows as Confidential: it has no company page and is not in the directory. If your ATS puts its own name in place of the company on confidential jobs, tell us in the integration request: we treat that name as "Confidential", and your brand never shows up as the hiring company.

Salary

  • Send it only when the employer discloses it: we never estimate salaries.
  • A single amount or a range, with currency and period: US$ 4000, US$ 3800 to US$ 4200 per month, US$ 25/hour.
  • Write thousands without a separator or with a dot (3800 or 3.800): a comma is always read as the decimal mark, so 3,800 becomes 3.80.
  • Without a period, we assume monthly. Jobs with a salary are included in the salary filter and in Google's structured data.

Location and language

  • City and state where the person will work. A fully remote job can come without a city, with isRemote = Yes.
  • Country as a 2-letter ISO code (BR, US, MX…). Without a country, the feed's default country applies.
  • Language: one feed per language (Portuguese, Spanish or English). The language is set on approval; for jobs in more than one language, send separate feeds.

Applying

  • Use the direct job URL on your ATS, with https://.
  • No home page, job list, URL shortener, WhatsApp, Telegram or email: the job gets a warning or is rejected.
  • We add utm_source=joonow&utm_medium=referral (if the URL already has utm_source, we keep yours). That way you measure applications coming from Joonow in your analytics.
  • Want the application in your system without the candidate leaving Joonow? Turn on applications by webhook.

Quality and review

Each job goes through risk rules before going live: asking the candidate for payment, applying through a messaging app, personal email in the description, shortened links, very short descriptions, salaries far from the role's reality, among others. Above the limit, the job is held for review by the team and does not show up until approved. The validator shows these signals before the integration.

Best practices for jobs to look good

  • Clear title with just the role: "HR Analyst", not "JOB 123 – HR ANALYST URGENT!!!".
  • Complete description (duties, requirements, benefits) in simple HTML with headings and lists. More than 200 characters.
  • Salary whenever the employer allows it.
  • The job owner's email on every job: it ranks higher and, if it gets reported, the team has someone to talk to.
  • Company website and logo on every job (and the description, if you have one): the logo shows in search and they help build the company page.
  • Correct city and state; remote jobs marked as remote.
  • Real dates for posting and, when there is one, expiration.
  • Stable ids: editing the job does not change the referencenumber.
  • One job, one record: the same job in several cities becomes one record per city, each with its own id.

On Google

Every Joonow job has its own page with JobPosting structured data built from your feed: baseSalary only with a disclosed salary, validThrough only when there is an expiration, remote jobLocationType only for fully remote jobs and the company name as hiringOrganization. Complete and correct data in the feed helps jobs show up in Google's job search.

Applications by webhook

Besides sending jobs, your ATS can receive applications from Joonow. With the webhook on, people who apply to a job in your feeds do it on Joonow itself: they see the company, your system as the destination and the list of what will be sent, they confirm, and Joonow delivers the application to your system, which creates the record on behalf of the client company. Jobs from partners that didn't turn it on work as always: the candidate goes to the apply URL. The ATS integration terms apply.

How to turn it on

In the partner panel, under Applications:

  1. Accept the integration terms (the version, the date and who accepted are recorded).
  2. Enter the HTTPS URL that receives deliveries: port 443, a domain name (not an IP) and no username or password in the URL. We don't follow redirects.
  3. Generate the secret key. It's shown once: keep it in a secrets vault.
  4. Send the test application (fake data, "test": true) and answer 2xx.
  5. Turn receiving on. Changing the URL turns it off until a new test.

The delivery

Each delivery is a POST to your URL, with Content-Type: application/json; charset=utf-8, a UTF-8 body and these headers:

Header Example What it's for
Joonow-Event-Id 0193f5c2-7b1e-7c4a-9d2e-5a1f0c3b8e21 Unique delivery id (the same id as the body): your idempotency key.
Joonow-Event-Type application.submitted Event type (the same type as the body).
Joonow-Timestamp 1793628191 Signing time, in Unix seconds.
Joonow-Signature v1=5d4a… HMAC-SHA256 of the key over {timestamp}.{body}, in hex.
User-Agent JoonowWebhooks/1.0 Identifies Joonow (not proof: the signature is the proof).

Your server has 10 seconds to answer.

Application body (application.submitted, version 1)

{
  "id": "0193f5c2-7b1e-7c4a-9d2e-5a1f0c3b8e21",
  "type": "application.submitted",
  "version": "1",
  "created_at": "2026-11-02T14:03:11Z",
  "test": false,
  "data": {
    "application": { "id": "0193f5c2-7b1e-7c4a-9d2e-5a1f0c3b8e21", "submitted_at": "2026-11-02T14:03:11Z", "source": "joonow" },
    "job": {
      "external_id": "ACME-4821",
      "joonow_id": "k3j9x2m4pq",
      "title": "Junior Support Analyst",
      "company": "Acme Logistics",
      "url": "https://www.joonow.com/en/job/junior-support-analyst-k3j9x2m4pq"
    },
    "candidate": {
      "name": "Maria Souza",
      "email": "maria.souza@example.com",
      "phone": "+1 305 555 0100",
      "location": { "city": "Miami", "region": "FL", "country": "US" },
      "experiences": [
        { "title": "Customer service representative", "company": "Example Store", "start": "2023-04", "current": true, "summary": "Customer service and after-sales." }
      ],
      "education": [
        { "course": "Business Administration", "institution": "Example College", "level": "undergraduate", "start": "2019-02", "end": "2022-12", "current": false }
      ],
      "skills": ["Customer service", "Excel"],
      "languages": [{ "name": "Spanish", "level": "intermediate" }],
      "salary_expectation": { "amount": 3000, "currency": "USD", "period": "month" }
    },
    "answers": [{ "question": "Are you available to work on Saturdays?", "answer": "Yes" }],
    "resume": {
      "file_name": "maria-souza.pdf",
      "content_type": "application/pdf",
      "size_bytes": 182344,
      "url": "https://www.joonow.com/api/partners/v1/resumes/4bZ9qT…",
      "expires_at": "2026-11-05T14:03:12Z"
    }
  }
}
Field Always sent? What it is
id yes Delivery id (UUID), equal to the Joonow-Event-Id header.
type yes application.submitted.
version yes 1. New fields may appear without a version change; a breaking change becomes 2, with 90 days' notice. Ignore what you don't know.
created_at yes When the candidate confirmed (ISO 8601, UTC).
test yes true for the panel's test application: answer 2xx, but don't create anyone.
data.application.id yes Application id (the same as the delivery). Use it to send the status back.
data.application.source yes joonow.
data.job.external_id yes The job id in your feed (referencenumber, partnerJobId).
data.job.joonow_id, title, company, url yes The job as it is on Joonow.
data.candidate.name, email yes Name and email of the candidate's account.
data.candidate.phone if filled in As the candidate typed it.
data.candidate.location if filled in city, region (state or province) and country (ISO 3166-1, 2 letters).
data.candidate.links reserved List of { "type", "url" }. Not sent yet: it comes when the profile has links.
data.candidate.experiences if filled in title, company, start and end (YYYY-MM), current, summary.
data.candidate.education if filled in course, institution, level (high_school, technical, undergraduate, postgraduate, masters, doctorate, course), start, end, current.
data.candidate.skills if filled in List of strings.
data.candidate.languages if filled in name and level (basic, intermediate, advanced, fluent, native).
data.candidate.salary_expectation if filled in amount, currency (ISO 4217) and period (hour, day, week, month, year).
data.answers yes (may be empty) question and answer: the answers to the job's questions.
data.resume if there is a resume file_name, content_type, size_bytes and the file: url with expires_at (link) or content_base64 (inside the delivery).

Only what the candidate filled in and saw on the confirmation screen is sent: empty fields are left out (no null and no empty lists, except answers). Sensitive data (such as disability) is not sent in this version, and neither are the job's sensitive questions: the confirmation screen doesn't show them.

Resume

  • Temporary link (default): data.resume.url is a signed GET valid for 3 days from each delivery attempt. Download it right away and store it in your system. The link needs no login: treat it as a secret and don't log it. Once expired, or after the candidate deletes the account, it answers 404.
  • Inside the delivery: choose it in the panel; the file goes in data.resume.content_base64 (PDF or DOCX, up to 5 MB).

Verifying the signature

  1. Read the raw body, the bytes as they arrived, before parsing JSON.
  2. Check that Joonow-Timestamp is at most 5 minutes from your clock, either way.
  3. Compute HMAC-SHA256(key, "{Joonow-Timestamp}.{body}") in lowercase hex and prefix it with v1=.
  4. Compare, in constant time, with each item of Joonow-Signature (comma separated). One match is enough: while rotating the key there are two, the new key's and the previous one's, for 24 hours.
  5. No valid signature or outside the window: answer 401 and store nothing.
import crypto from 'node:crypto';

function validSignature(rawBody, headers, key) {
  const t = headers['joonow-timestamp'] ?? '';
  if (!/^\d+$/.test(t) || Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
  const expected = Buffer.from('v1=' + crypto.createHmac('sha256', key).update(t + '.').update(rawBody).digest('hex'));
  return (headers['joonow-signature'] ?? '').split(',').map((s) => Buffer.from(s.trim()))
    .some((s) => s.length === expected.length && crypto.timingSafeEqual(s, expected));
}

Response, idempotency and retries

  • Answer 2xx only after storing the application. The response body is ignored.
  • The same id may arrive more than once (a retry after a network failure, or the candidate resending an application that didn't arrive). If you already have that id, answer 2xx without creating it again.
  • Any other answer, or none within 10 seconds, is a failure. A redirect (3xx) is a failure too.
  • We retry with growing intervals (1 min, 5 min, 30 min, 2 h, 6 h and then every 12 h) up to 72 hours after the confirmation. Then we stop and email the candidate and your ATS contact.
  • 410 Gone means "this job no longer accepts applications": we stop right away and let people know.
  • The panel shows each delivery, the attempts, the last response and the failures.

Status back

So the candidate can follow along on Joonow, send each application's status to https://www.joonow.com/api/partners/v1/events, with POST, Content-Type: application/json and the same Joonow-Timestamp and Joonow-Signature, computed with your key the same way.

{ "type": "application.in_review", "application_id": "0193f5c2-7b1e-7c4a-9d2e-5a1f0c3b8e21", "occurred_at": "2026-11-03T10:15:00Z" }
  • type: application.received (stored), application.in_review (being reviewed) or application.closed (the process ended for the candidate). The status only moves forward: a late event doesn't move it back.
  • Responses: 200 with {"ok":true,"applied":true} (or false, when nothing changed), 400 for an unknown event, 401 for a wrong signature, time or id, 413 above 16 KB and 429 when there are too many.
  • The test application accepts the status too: use it to test the way back.
  • The candidate sees the status only in their own area and gets an email when the application goes into review or is closed.

Correction and erasure requests

When a candidate asks Joonow to correct or erase their data, we notify every system that received an application from them (LGPD, art. 18, § 6), through the same webhook, with the same signature and the same retries:

{
  "id": "0193f611-2c40-7e2b-8a51-0d9e7f3a1c55",
  "type": "candidate.erasure_requested",
  "version": "1",
  "created_at": "2026-11-20T09:00:00Z",
  "test": false,
  "data": {
    "reason": "account_deleted",
    "candidate": { "email": "maria.souza@example.com" },
    "applications": [{ "id": "0193f5c2-7b1e-7c4a-9d2e-5a1f0c3b8e21", "job_external_id": "ACME-4821", "submitted_at": "2026-11-02T14:03:11Z" }],
    "respond_by": "2026-12-05T09:00:00Z"
  }
}
  • candidate.erasure_requested: erase (or ask the client company to erase) what came from Joonow. reason is account_deleted (the candidate deleted the account) or candidate_request (asked through the privacy center).
  • candidate.correction_requested: data.candidate carries the current data, in the same format as the application, to replace what you received.
  • Pass it on to the client company and confirm within 15 days (respond_by) with an event back: { "type": "candidate.erasure_completed", "request_id": "<request id>" } (or candidate.correction_completed).

Security

  • HTTPS only, with TLS 1.2 or newer. Reject deliveries without a valid signature or outside the 5-minute window.
  • Keep the key in a secrets vault and rotate it in the panel if you suspect a leak.
  • Don't log application bodies or resume links in open logs.
  • Deliveries come from IP addresses that may change: trust the signature, not the IP.

How to request the integration

  1. Build the feed following this specification.
  2. Paste the URL into the validator and fix what it points out.
  3. With the feed validated, fill in the request right there. The team reviews it within 2 business days.
  4. Once approved, you get access to the partner dashboard by email, with reads, live jobs, rejections and clicks per month.

Technical questions? Talk to us through Contact us.