Skip to content

Request a takedown

POST
/core/api/takedowns/
curl --request POST \
--url https://app.nebty.de/core/api/takedowns/ \
--header 'Authorization: <Authorization>' \
--header 'Content-Type: application/json' \
--data '{ "target_website": "https://example.com", "user_comment": "example", "brand": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "authorization_consent": true, "accepted_price": "example", "accepted_currency": "USD" }'

Requests a takedown of a website. Send target_website (an http or https URL on a public host; localhost and non-public IP addresses are rejected) and optionally brand (UUID) and user_comment.

If you pass brand, the API key’s user must be a member of it, otherwise the request is rejected with 400. Once nebty enforces the price consent, a user who is a member of a brand that takes it must pass brand; without it the request is rejected with 400 and code: brand_required.

The new takedown starts as OPEN or as REQUESTED (not yet started; nebty checks it first and then moves it to OPEN, or to REJECTED). Read status in the 201 response; do not assume either.

Price consent. For some brands an order is billed at a price per successful takedown that the person ordering must accept. Then send the accepted price as accepted_price (decimal string, net, VAT on top) and accepted_currency (EUR, USD or CAD), both or neither. Sending them is a binding order at that price: show the price to a person and let them accept it before you send it, and never fill it in from an error response by itself. A price that no longer matches is rejected with 409 and code: price_changed; once nebty enforces the consent, an order without it is rejected with 400 and code: price_consent_required. Both bodies carry the current price as price: {amount, currency}. For brands that take no price consent, sending the fields is rejected with 400 and code: price_not_applicable; leave them out. The accepted price is returned as price and price_currency on the takedown, and nebty mails the requesting user a confirmation of the order with the price and the next step.

One active case per website. If the brand (or, without brand, the API key’s user) already has an active takedown (REQUESTED, OPEN, IN_PROGRESS or PENDING_RESPONSE) for the same host, the request is rejected with 409, code: duplicate and the existing case’s id as takedown_id. The host is compared without case and a leading www.; a subdomain is another host. Nothing is created or billed.

Once nebty enforces the signed Power of Attorney, also send authorization_consent: true (you confirm you are authorized to request the takedown for the brand), and the brand needs an active signed Power of Attorney. Without one the request is rejected with 400 and code: poa_required; a brand admin grants it in the nebty dashboard. Until then the field is accepted and ignored.

Serializer for creating new takedown requests.

object
target_website
required

The target website URL for the takedown request

string format: uri
<= 500 characters
user_comment

Optional comment from the requesting user

string
nullable
brand

Brand associated with this takedown. All users with access to this brand can view the takedown.

string format: uuid
nullable
authorization_consent

The caller confirms they are authorized to request this takedown for the brand. Required (true) for customers once Power of Attorney enforcement is on.

boolean
accepted_price

The price per successful takedown the person ordering was shown and accepted (net, VAT on top), from the takedown quote. Send it together with accepted_currency, and only when the quote asks for consent.

string format: decimal
/^-?\d{0,8}(?:\.\d{0,2})?$/
accepted_currency

The currency of accepted_price.

  • USD - US$
  • CAD - CA$
  • EUR - EUR
string
Allowed values: USD CAD EUR
Media typeapplication/json

Serializer for takedown request details.

object
id
required
string format: uuid
target_website
required

The target website URL for the takedown request

string format: uri
<= 500 characters
category

What the case is against. ‘token’ is a fake crypto token (smart contract); target_website then holds the contract’s block-explorer URL, and the domain autofill and post-close rescan skip the row. Only staff may set ‘token’.

  • website - Website
  • token - Token
string
Allowed values: website token
token_platform

Token only: the specific listing or trading platform covered by the customer’s order.

string format: uri
<= 500 characters
token_objective
One of:
  • listing_removed - Remove the agreed token listing
  • trading_blocked - Block trading on the agreed platform
string
Allowed values: listing_removed trading_blocked
token_agreed_at
required

Server timestamp when the complete token order scope was first recorded. The scope is then immutable.

string format: date-time
nullable
requesting_user_email
required
string
user_comment

Optional comment from the requesting user

string
nullable
brand

Brand associated with this takedown. All users with access to this brand can view the takedown.

string format: uuid
nullable
brand_display
required
string
nullable
brand_name

Legacy free-text brand name (deprecated, use brand FK instead)

string
nullable <= 255 characters
status
required

Current status of the takedown request

  • REQUESTED - Pending review
  • OPEN - Open
  • IN_PROGRESS - In Progress
  • PENDING_RESPONSE - Pending Response
  • CLOSED - Closed
  • FAILED - Failed
  • REJECTED - Rejected
string
Allowed values: REQUESTED OPEN IN_PROGRESS PENDING_RESPONSE CLOSED FAILED REJECTED
status_display
required
string
is_open
required
boolean
closed_at
required

Timestamp when the takedown case was closed.

string format: date-time
nullable
closed_at_source
required
One of:
  • MEASURED - Measured at closure
  • DERIVED_FROM_EVENT - Derived from status-change event
  • DERIVED_FROM_NOTE - Derived from last case note (±1 day)
string
Allowed values: MEASURED DERIVED_FROM_EVENT DERIVED_FROM_NOTE
resolution
required
One of:
  • DOMAIN_SUSPENDED - Domain Suspended
  • CONTENT_REMOVED - Content Removed
  • SERVER_HOLD - Server Hold
  • VOLUNTARY_TAKEDOWN - Voluntary Takedown
  • UNRESOLVED - Unresolved
  • FALSE_POSITIVE - False Positive
  • TOKEN_LISTING_REMOVED - Agreed token listing removed
  • TOKEN_TRADING_BLOCKED - Trading blocked on agreed platform
  • TOKEN_WARNING_ADDED - Token warning added (partial mitigation)
string
Allowed values: DOMAIN_SUSPENDED CONTENT_REMOVED SERVER_HOLD VOLUNTARY_TAKEDOWN UNRESOLVED FALSE_POSITIVE TOKEN_LISTING_REMOVED TOKEN_TRADING_BLOCKED TOKEN_WARNING_ADDED
resolution_display
required
string
nullable
price
required

Price per successful takedown, net plus VAT, that the customer accepted with the order. 0.00 is a real price; null means no price was frozen.

string format: decimal
nullable /^-?\d{0,8}(?:\.\d{0,2})?$/
price_currency
required
One of:
  • USD - US$
  • CAD - CA$
  • EUR - EUR
string
Allowed values: USD CAD EUR
registrar

Domain registrar, e.g. ‘Openprovider’, ‘Sav.com’

string
nullable <= 255 characters
domain_created_at

Domain registration date from WHOIS.

string format: date
nullable
domain_expires_at

Domain expiry date from WHOIS.

string format: date
nullable
domain_status

WHOIS status, e.g. ‘clientTransferProhibited’, ‘serverHold’

string
nullable <= 255 characters
ip_address

Resolved IP address (may be proxy IP).

string
nullable
origin_ip

Real server IP behind CDN/proxy.

string
nullable
asn

AS number, e.g. ‘AS13335’

string
nullable <= 20 characters
hosting_provider

Hosting provider, e.g. ‘Hostinger’, ‘Hetzner’

string
nullable <= 255 characters
cdn_proxy

CDN/proxy provider, e.g. ‘Cloudflare’

string
nullable <= 255 characters
is_proxied

Whether the domain is behind a CDN/proxy.

boolean
backend_provider

Backend service, e.g. ‘Supabase’, ‘Vercel’

string
nullable <= 255 characters
backend_project_id

Project ID at backend provider.

string
nullable <= 255 characters
ssl_issued_at

SSL certificate issue date.

string format: date
nullable
ssl_expires_at

SSL certificate expiry date.

string format: date
nullable
ssl_issuer

Certificate issuer, e.g. ‘Let’s Encrypt’, ‘Cloudflare’

string
nullable <= 255 characters
a_entry

DNS A record information (DEPRECATED - use dns_raw)

string
nullable
ns_entry

DNS NS record information (DEPRECATED - use dns_raw)

string
nullable
dns_raw

Full DNS records as JSON. Expected structure: {“a”: […], “aaaa”: […], “cname”: […], “mx”: […], “ns”: […], “txt”: […], “soa”: […], “caa”: […]}

nullable
virustotal_score

Score, e.g. ‘16/93’

string
nullable <= 20 characters
virustotal_url

Link to VirusTotal report.

string format: uri
nullable <= 200 characters
urlscan_url

Link to urlscan.io result.

string format: uri
nullable <= 200 characters
screenshot_url

URL to screenshot in Hetzner S3 Object Storage.

string format: uri
nullable <= 2000 characters
screenshot_taken_at

When the screenshot was taken.

string format: date-time
nullable
abuse_contacts
required
Array<object>

Serializer for abuse contact details.

object
id
required
string format: uuid
contact_type
required
  • REGISTRAR - Registrar
  • HOSTING - Hosting Provider
  • CDN - CDN / Proxy
  • BACKEND - Backend Service
  • REGISTRY - Domain Registry
  • OTHER - Other
string
Allowed values: REGISTRAR HOSTING CDN BACKEND REGISTRY OTHER
contact_type_display
required
string
provider_name
required

Provider name, e.g. ‘Cloudflare’, ‘Openprovider’

string
<= 255 characters
abuse_email

Abuse email address.

string format: email
nullable <= 254 characters
abuse_form_url

URL to abuse report form.

string format: uri
nullable <= 200 characters
report_status
  • NOT_SENT - Not Sent
  • SENT - Sent
  • ACKNOWLEDGED - Acknowledged
  • ACTION_TAKEN - Action Taken
  • REJECTED - Rejected
  • NO_RESPONSE - No Response
string
Allowed values: NOT_SENT SENT ACKNOWLEDGED ACTION_TAKEN REJECTED NO_RESPONSE
report_status_display
required
string
reported_at
string format: date-time
nullable
response_received_at
string format: date-time
nullable
case_reference

Provider case reference, e.g. ‘Case 00954977’

string
nullable <= 255 characters
notes
string
nullable
created_at
required
string format: date-time
updated_at
required
string format: date-time
blacklist_submissions
required
Array<object>

Serializer for blacklist submission details.

object
id
required
string format: uuid
tier
required
  • P1 - P1 - Immediate (GSB, Netcraft, SmartScreen)
  • P2 - P2 - Distribution (Spamhaus, Openphish, SpamCop)
  • P3 - P3 - Prevention (VirusTotal, Symantec, ScamAdviser)
string
Allowed values: P1 P2 P3
tier_display
required
string
service_name
required

Blacklist service name, e.g. ‘Google Safe Browsing’, ‘Spamhaus’

string
<= 255 characters
submission_url

URL for submission.

string format: uri
nullable <= 200 characters
status
  • PENDING - Pending
  • SUBMITTED - Submitted
  • LISTED - Listed
  • REJECTED - Rejected
string
Allowed values: PENDING SUBMITTED LISTED REJECTED
status_display
required
string
submitted_at
string format: date-time
nullable
confirmed_at

When listing was confirmed.

string format: date-time
nullable
created_at
required
string format: date-time
updated_at
required
string format: date-time
created_at
required
string format: date-time
updated_at
required
string format: date-time
Example
{
"category": "website",
"token_objective": "listing_removed",
"status": "REQUESTED",
"closed_at_source": "MEASURED",
"resolution": "DOMAIN_SUSPENDED",
"price_currency": "USD",
"abuse_contacts": [
{
"contact_type": "REGISTRAR",
"report_status": "NOT_SENT"
}
],
"blacklist_submissions": [
{
"tier": "P1",
"status": "PENDING"
}
]
}

Invalid request data (field errors directly on the response), a refused order with a code (poa_required, brand_required, price_not_applicable), or code: price_consent_required with the current price.

Media typeapplication/json
Any of:
object
detail
required
string
Example
{
"target_website": [
"Target host is not a public address."
]
}

The API key is missing, invalid, revoked or belongs to an inactive user.

Media typeapplication/json
object
detail
required
string
Examplegenerated
{
"detail": "example"
}

code: price_changed: the accepted_price no longer matches. The body carries the current price as price: {amount, currency}; show it to the person ordering and order again. code: poa_not_approved (staff keys only): the brand’s Power of Attorney is still under review. code: duplicate: an active takedown for this host exists; takedown_id is its id.

Media typeapplication/json
Any of:
object
detail
required
string
Example
{
"code": "price_changed",
"detail": "The price has changed. Show the new price and order again.",
"price": {
"amount": "400.00",
"currency": "EUR"
}
}

Too many requests or failed authentication attempts. Try again later.

Media typeapplication/json
object
detail
required
string
Examplegenerated
{
"detail": "example"
}